我正在基于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
分段错误(核心转储)
答案 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]
您的逻辑中存在相当多的错误,原因是您希望代码的行为与您真正理解的内容有何不同。使用调试器来了解故障发生的位置并检查所涉及的变量可能很有用。
编辑:
您要为G
分配一个较小的大小,因为malloc(sizeof(struct Graph*))
相当于malloc(sizeof(void*))
(分配一个指针的大小),您需要malloc(sizeof(struct Graph))
第二次编辑:
注意到j
圈for(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。
此外,您需要检查u
和v
的输入值是否在
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。