使用C中的邻接矩阵创建图形

时间:2018-06-01 03:17:27

标签: c struct segmentation-fault malloc

我正在基于C中的邻接矩阵实现图形程序。 但我正在初始化矩阵(分配零值)时出现分段错误。 我不确定我是否在访问双指针时遇到任何错误。

有人可以帮我解决这个问题吗?

以下是代码:

struct Graph {
    int V;
    int E;
    int **adj;
};


struct Graph *addelements() {
    int i,j,a,u,v;  

    struct Graph *G= (struct Graph*)malloc(sizeof(struct Graph*));
    printf("Enter the number of vertices and edges : ");
    scanf("%d %d", &G->V,&G->E);;
    printf("%d, %d\n",G->V ,G->E);
    //G->adj = (int **)malloc(sizeof(int **)*(G->V * G->E));
    G->adj = malloc(sizeof(G->V * G->E));

    //Initialization of vertices

    for(i=0;i<=G->V;i++) {
        for(j=0;i<=G->V;j++) {
            G->adj[i][j]=0;
        }
    }


    //Reading the edges;
    for(i=0;i<G->E;i++) {
        printf("Enter the source and destination : ");  
        scanf("%d %d\n", &u,&v);       
        G->adj[u][v]=1;    
        G->adj[v][u]=1;
    }

    //printing the matrix

    for(i=0;i< G->V;i++) {
        for(j=0;i< G->V;j++) {
            printf("%d", G->adj[i][j]);4
        }
    }

   return G;
}


int main() {  
    struct Graph *a= (struct Graph*)malloc(sizeof(struct Graph*)); 
    a =  addelements();  
} 

输出:

  

输入顶点和边数:4 5

     

分段错误(核心转储)

3 个答案:

答案 0 :(得分:2)

如你所说,你的错误就在那里

G->adj = malloc(sizeof(G->V * G->E));

//Initialization of vertices

for(i=0;i<=G->V;i++)
{
  for(j=0;j<=G->V;j++) 
  {
    G->adj[i][j]=0;
  }
}
  • 您正在adj[V][V]写信,其中您分配的sizeof(G->V * G->E)大小为sizeof(int)(一个整数),即使您最多需要adj[V][E] }

  • 此外,您正在分配1D阵列并访问2D阵列,访问adj[0][0]将首先尝试读取adj[0]作为指向数组的指针(未定义的值)并尝试写信至undefined[0]

使用malloc( G->V * G->V * sizeof(int) )分配,并使用adj[i*V+j]

进行访问/编写

您的逻辑中存在相当多的错误,原因是您希望代码的行为与您真正理解的内容有何不同。使用调试器来了解故障发生的位置并检查所涉及的变量可能很有用。

编辑:

同时提及other answers

您要为G分配一个较小的大小,因为malloc(sizeof(struct Graph*))相当于malloc(sizeof(void*))(分配一个指针的大小),您需要malloc(sizeof(struct Graph))

第二次编辑:

注意到jfor(j=0;i<=G->V;j++)中的拼写错误for(j=0;j<=G->V;j++)

答案 1 :(得分:1)

你只是一个指针malloc空间。改为使用:

malloc(sizeof(struct Graph));

答案 2 :(得分:1)

我认为你需要修改

struct Graph *G= (struct Graph*)malloc(sizeof(struct Graph*));

struct Graph *G= malloc(sizeof(struct Graph));

因为您需要分配空间来存储结构变量而不是指针。

您还没有为G->adj正确分配空间。

尝试

G->adj = malloc(sizeof(int **));
for(int i=0; i<G->V; ++i)
{
    G->adj[i]=malloc(sizeof(int)*G->V);
}

将你的循环修改为

for(i=0;i<G->V;i++)
{
   for(j=0;j<G->V;j++) 
   {
      G->adj[i][j]=0;
   }
}

即,将<=更改为<以防止访问数组的边界。

在阅读边缘时,不要做

scanf("%d %d\n", &u,&v);       

最后的换行符。请参阅this

此外,您需要检查uv的输入值是否在

范围内
for(i=0;i<G->E;i++)  
{
    printf("Enter the source and destination : ");  
    scanf("%d %d", &u,&v);       
    if(u<G->V && v<G->V)
    {
        G->adj[u][v]=1;    
        G->adj[v][u]=1;
    }
    else
    {
        printf("\ninvalid value. Try again.");
        i--;
    }
}

并且您不需要为struct中的main()指针分配空间,因为您已经为addelements()函数中存储在该指针中的值分配了内存。否则会导致内存泄漏。

所以,在main()中,做

struct Graph *a= addelements();

请注意,malloc()如果无法分配内存,则返回NULL。您需要检查malloc()调用是否也失败。

您无需在C语言中转换malloc()的返回值。阅读this