Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用邻接矩阵创建图形_C_Function_Matrix_Graph_Malloc - Fatal编程技术网

C 使用邻接矩阵创建图形

C 使用邻接矩阵创建图形,c,function,matrix,graph,malloc,C,Function,Matrix,Graph,Malloc,这是我的结构 struct node{ int V,E; int **adj; }; 以下是我创建图形的代码: struct node* create() { int i,j,x,y; struct node *G=malloc(sizeof(struct node)); printf("Write the number of vertex and edges\n"); scanf("%d%d",&G->V,&G->E

这是我的结构

struct node{
    int V,E;
    int **adj;
};
以下是我创建图形的代码:

struct node* create()
{
    int i,j,x,y;
    struct node *G=malloc(sizeof(struct node));
    printf("Write the number of vertex and edges\n");
    scanf("%d%d",&G->V,&G->E);
    G->adj=malloc(sizeof(int)*(G->V * G->V));
    if(!G->adj){
        printf("Out of memory\n");
        return;
    }
    for(i=0;i<G->V;i++)
    for(j=0;j<G->V;j++)
    G->adj[i][j]=0;
    printf("\nWrite the source node and destination: ");
    for(i=0;i<G->E;i++){
    scanf("%d%d",&x,&y);
    G->adj[x][y]=1;
    G->adj[y][x]=1;
    }
    return(G);
}

当我编译程序时,会询问顶点和边的数量,但一旦输入值,我的程序就会崩溃。我想知道原因。这是因为内存分配失败吗?

C99样式的变长数组仅对局部变量或参数有用。因此,有两种经典的C方法可用于实现2D数组

  • 指针数组:
  • 这就是您的结构的外观。这样,指针数组和数据需要单独分配:

    G->adj = calloc(G->V, sizeof (int*));
    assert(G->adj != NULL); /* need assert.h for this */
    for (i=0; i<G-V; ++i)
    {
        G->adj[i] = calloc(G->V, sizeof (int));
        assert(G->adj[i] != NULL);
    }
    

    就这样。现在,当您访问一个元素时,使用
    G->adj[i*G->V+j]
    ,而不是
    G->adj[i][j]
    。宏可能有助于提高可读性。

    我看到的是小的NIT。不检查有效输入(顶点计数、边计数、输入图形边时的节点编号)、不检查G是否为NULL以及malloc返回NULL时返回语句中没有值。最后一位甚至不会在我使用的编译器上编译。关于邻接矩阵的两个注意事项:首先,calloc()会为您将矩阵归零,如果您的矩阵将全部为0和1值,您可以通过使用
    char
    而不是
    int
    为元素类型节省内存。但首先,你可能想说你使用了什么输入…@MikeHousky,没关系!但是我的记忆力没有问题。我有一个4GB内存。我的代码有问题。你能猜出是怎么回事吗?“但首先,你可能想说你使用的是什么输入。”在返回语句修复后,我在编译时没有发现错误。我使用4表示顶点数,5表示边数。对于邻接矩阵,我将使用0和1,当然有可变长度的2d数组,尽管你是正确的,因为这样的数组不能存储到全局结构中。但是,您使用的
    assert
    是不正确的,因为
    assert
    用于表示不变量,即在正确的代码中永远不会发生的事情,但是
    calloc
    可以返回
    NULL
    内存耗尽,即使程序是正确的。@AnttiHaapala两个维度在2D VLA中是否都会变化?(我不使用它们,因为我需要编译的东西-UGH——Visual C++)。无论如何,断言只是在调试期间停止测试运行,如果有任何故障。断言失败对于生产来说是一个糟糕的UI,即使没有语义上的异议。是的,两个维度都可能不同。但事实上,可变修改类型的有限范围意味着它不是这里的答案。
    G->adj = calloc(G->V, sizeof (int*));
    assert(G->adj != NULL); /* need assert.h for this */
    for (i=0; i<G-V; ++i)
    {
        G->adj[i] = calloc(G->V, sizeof (int));
        assert(G->adj[i] != NULL);
    }
    
    G->adj = calloc(G->V * G->V, sizeof (int));
    assert(G->adj != NULL);