C语言邻接矩阵图初始化遇段错误,请求排查解决
排查邻接矩阵图程序的段错误问题
你的代码里有好几处关键错误,直接导致了段错误,我来逐个帮你分析和修正:
1. 结构体内存分配错误
在addelements函数里,你分配Graph结构体时写了:
struct Graph *G= (struct Graph*)malloc(sizeof(struct Graph*));
这里你只分配了一个指针的大小,但实际上需要分配整个struct Graph结构体的内存空间,应该改成:
struct Graph *G = malloc(sizeof(struct Graph));
(注:C语言里不需要强制转换malloc的返回值,强制转换反而可能隐藏一些编译警告)
2. 邻接矩阵的内存分配完全错误
邻接矩阵是V×V的二维数组,你原来的分配方式完全不符合二维数组的内存逻辑:
G->adj = malloc(sizeof(G->V * G->E));
正确的做法是先分配V个指向int的指针(对应矩阵的行),然后为每一行分配V个int的空间(对应每行的列):
// 先分配行指针数组 G->adj = malloc(sizeof(int*) * G->V); // 为每行分配列空间 for (int i = 0; i < G->V; i++) { G->adj[i] = malloc(sizeof(int) * G->V); }
3. 循环条件错误导致越界访问
初始化矩阵的嵌套循环里,内层循环的条件写错了——把j的判断写成了i,而且如果顶点是从0开始编号的话,循环应该用< G->V而不是<=(比如V=4时,合法顶点编号是0-3,循环到i<4就足够了)。修正后:
for(i=0; i < G->V; i++) { for(j=0; j < G->V; j++) { G->adj[i][j] = 0; } }
同样,后面打印矩阵的循环也犯了同样的错误,内层循环误写为i < G->V,要改成j < G->V。
4. scanf格式符的错误
读取边的scanf里多了一个\n:
scanf("%d %d\n", &u,&v);
这个\n会导致程序等待额外的输入,甚至引发输入逻辑错误,直接去掉即可:
scanf("%d %d", &u, &v);
5. main函数的内存泄漏
main函数里你先malloc了a,然后又把addelements的返回值赋值给a,导致之前malloc的内存无法被释放,直接改成:
int main() { struct Graph *a = addelements(); // 记得用完后释放内存,避免泄漏 if (a != NULL) { for (int i = 0; i < a->V; i++) { free(a->adj[i]); } free(a->adj); free(a); } return 0; }
修正后的完整代码
#include <stdio.h> #include <stdlib.h> struct Graph { int V; int E; int **adj; }; struct Graph *addelements() { int i,j,u,v; struct Graph *G = malloc(sizeof(struct Graph)); if (G == NULL) { // 检查malloc是否成功,避免空指针 printf("Memory allocation failed for Graph\n"); return NULL; } 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 = malloc(sizeof(int*) * G->V); if (G->adj == NULL) { printf("Memory allocation failed for adj rows\n"); free(G); return NULL; } for (i = 0; i < G->V; i++) { G->adj[i] = malloc(sizeof(int) * G->V); if (G->adj[i] == NULL) { printf("Memory allocation failed for adj column %d\n", i); // 释放已分配的内存,避免泄漏 for (int k = 0; k < i; k++) { free(G->adj[k]); } free(G->adj); free(G); return NULL; } } // 初始化矩阵为0 for(i=0; i < G->V; i++) { for(j=0; j < G->V; j++) { G->adj[i][j] = 0; } } // 读取边,增加合法性检查 for(i=0; i < G->E; i++) { printf("Enter the source and destination : "); scanf("%d %d", &u, &v); if (u >= 0 && u < G->V && v >=0 && v < G->V) { G->adj[u][v] = 1; G->adj[v][u] = 1; } else { printf("Invalid vertex number! Please enter values between 0 and %d\n", G->V-1); i--; // 重新输入当前边 } } // 打印矩阵 printf("Adjacency Matrix:\n"); for(i=0; i < G->V; i++) { for(j=0; j < G->V; j++) { printf("%d ", G->adj[i][j]); } printf("\n"); } return G; } int main() { struct Graph *a = addelements(); // 释放内存 if (a != NULL) { for (int i = 0; i < a->V; i++) { free(a->adj[i]); } free(a->adj); free(a); } return 0; }
额外提示:记得每次malloc后检查是否分配成功,避免空指针访问;同时用完内存后要释放,防止内存泄漏。
内容的提问来源于stack exchange,提问作者Ankita
相关产品推荐
相关产品推荐

