You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:58:22