【问题标题】:Dynamic Allocation of 2D Array二维数组的动态分配
【发布时间】:2013-07-11 01:56:38
【问题描述】:

我正在使用邻接矩阵实现图,但我无法解决分段错误。谁能帮我指导二维矩阵的动态分配?我还想知道二维数组如何存储在内存中以及如何访问它。

#include<stdio.h>
#include<stdlib.h>

struct Graph{
int V; // To represent number the vertex...
int E; //To represent number the Edge.....
int **Adj; // Two dimensional matrix to form the adjacency matrix... 
};


struct Graph *adjMatrixOfGraph(){

        int i;    //for scanning the edges between them .... 
        int u,v; // for loop while initliasing the  adjacency matrix... 
        struct Graph *G=(struct Graph*) malloc(sizeof(struct Graph)); //

        if(!G){
        printf("Memory Error");
        return;
        }

        printf("Number of Vertices");

        scanf("%d",&G->V);
        printf("%d",G->V);
        printf("Number of Edges");
        scanf("%d",&G->E);
        G->Adj=(int **)malloc(sizeof(G->V * G->V)); //allocating memory for G->Adj);
        /*Dynamic memory allocation for Two Dimensional Arrays */

/*      G->Adj = malloc(G->V * sizeof(int )); 
            if(G->Adj == NULL) {         
                 printf( "out of memory\n");     
                }     

         for(i = 0; i < G->V; i++) {     
                G->Adj[i] = malloc(G->V * sizeof(int ));     
                if(G->Adj[i] == NULL) {         
                printf( "out of memory\n");     


                } 
                }
*/

        if(!G->Adj)
        {
        printf("Memory Error");
        return;
        }


        for(u=0;  u < G->V; u++){
        for(v=0; v < G->V; v++){
         //printf("%d %d",u,v); 
         G->Adj[u][v]=0;  //initalising the complete adjacency matrix to zero.
        }
        }

        //Enter the edges.. and the vertices.
        //We are considering this graph as undirected one ... 
        for(i=0;i< G->E;i++)
        {
        scanf("Reading Edges %d %d ",&u,&v);
        G->Adj[u][v]=1;
        G->Adj[u][v]=1;

        //if this graph was directed then we should have considere only one side... 
        //G->V[u][v]=1;

        }


return G;
}

main()
{
struct Graph *G1=adjMatrixOfGraph();

//struct Graph *adjMatrixOfGraph(){
printf("Successful");
return 0;
}

【问题讨论】:

    标签: c graph segmentation-fault multidimensional-array


    【解决方案1】:

    int **Adj分配内存的方式如下:

    首先你为你将拥有的指向整数的指针分配内存:

    Adj = malloc(sizeof(int*) * number_of_integers); /* notice what I pass to sizeof */
    

    接下来为每个整数分别分配内存:

    for (i = 0; i < number_of_integers; i++)
        Adj[i] = malloc(sizeof(int) * G->E);
    

    当然,每个malloc 调用之后都需要一个free 调用,以类似的方式。

    注意我没有cast the result of malloc

    我对您的代码做了一些其他更改:

    更新您的 scanf 以确保缓冲区中剩余的换行符没有问题:

        printf("Number of Vertices: ");
        scanf(" %d", &G->V);
        printf("Number of Edges: ");
        scanf(" %d", &G->E);
    

    初始化它们(或者,查找 calloc,因为它会为您进行零初始化):

        for(u=0;  u < G->V; u++) // for each vertice
        {
            for(v=0; v < G->E; v++) // for each edge
            {
                G->Adj[u][v] = 0;
            }
        }
    

    我不确定下面的部分,您手动将边缘设置为 1,对吗?你不应该使用G-&gt;V而不是G-&gt;E吗?

        for(i = 0; i < G->V; i++)
        {
            printf("Reading vertice u: ");
            scanf(" %d",&u);
            printf("Reading edge v: ");
            scanf(" %d",&v);
    
            if (u > G->V || v > G->E) // simple error handling 
            {
                printf("Input bigger than size of vertice/edges\n");
                exit(1);
            }
    
            G->Adj[u][v] = 1;
    
            G->Adj[u][v] = 1;
        }
    

    之后我可以打印Successful。如果您想让这更容易一点,请使用-g 标志编译您的代码,如果您使用的是Linux,请使用ulimit -c unlimited。每次遇到段错误时,这将创建一个 coredump 文件。

    然后要查看问题出在哪里,运行gdb your_app core 并在内部运行backtrace。我无法强调在这些情况下使用调试器的重要性。

    【讨论】:

    • number_of_integers 表示 n * n ?,其中 n 是行数或列数
    • 您计划存储在二维数组中的整数数量,如果我正确理解您的代码,在您的情况下它将是 G-&gt;V
    • @NileshAgrawal 我已经对我的帖子进行了一些更改,请您看一下,如果它可以帮助您运行代码,请告诉我?一旦你malloc-ed,我有点不清楚每个整数数组应该有多大。我认为malloc 实际上应该是Adj[i] = malloc(sizeof(int) * G-&gt;E);。这是一个正确的假设吗?
    • Adj[i]=malloc(sizeof(int) *G->V)
    • 我觉得scanf也给你带来了一些问题,让我再仔细检查一下代码。
    【解决方案2】:
    int **allocate_2D_array(int rows, int columns)
    {
        int k = 0;
        int **array = malloc(rows * sizeof (int *) );
    
        array[0] = malloc(columns * rows * sizeof (int) );
        for (k=1; k < rows; k++)
        {
            array[k] = array[0] + columns*k;
            bzero(array[k], columns * sizeof (int) );
        }
    
        bzero(array[0], columns * sizeof (int) );
    
        return array;
    }
    

    【讨论】:

    • 这是一个 BSD 扩展,使用 memset (array[0], 0, columns * sizeof (int)) 代替。
    • man bzero 表明bzero 以任何方式将空字节写入字符串。很少使用零以外的值作为空指针的操作系统会抱怨。零作为 C 中的空指针并不意味着内部表示全为零,尽管这是下注的方式。
    猜你喜欢
    • 1970-01-01
    • 2013-11-24
    • 2021-02-03
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    相关资源
    最近更新 更多