初始化结构中的分段错误

时间:2017-06-03 19:18:35

标签: c

我的目标是实现一个算法来检查图形是否是拓扑的。但是,这不是问题。在尝试使用给定数据初始化我的图形结构时,我得到了核心转储。

Program received signal SIGSEGV, Segmentation fault.
0x00000000004009a3 in initGraph (numberNode=15, numberArc=17, g=0x1) at src/topologicGraphOp.c:45
45          g->numberNode = numberNode;

我真的很困惑,因为这个问题看起来很明显但是,经过各种尝试后我找不到它所以我希望有人会发现像“呸,这很明显”这样的愚蠢错误,因为嗯......我运气不好......

这是结构:

typedef struct {
   int numberNode;
   int numberArc;

   int *distances;
   int *predecessors;

   float **matrix; 
   queue *successors;

   char *graphTitle;
   char **nodeDescription;
   int *time;

} graph;

核心转储似乎出现的功能:

void initGraph(int numberNode, int numberArc, graph *g) {
    int i, j;

    g->numberNode = numberNode;
    g->numberArc = numberArc;
    g->nodeDescription = malloc(numberNode * sizeof (char));
    g->matrix = (float **) calloc(g->numberNode, sizeof (float*));

    for (i = 0; i < g->numberNode; i++) {
        g->matrix[i] = (float *) calloc(g->numberNode, sizeof (float));
        g->nodeDescription[i] = malloc(sizeof (char));
    }
}

我的主要功能只是调用初始化函数。 非常感谢!

编辑:评论中的解决方案:) 在函数中使用它之前我忘记了malloc我的图形指针。

2 个答案:

答案 0 :(得分:1)

分段错误几乎总是意味着你正在以某种方式弄乱指针。无论是在分配期间还是在解除引用期间(对于阅读或写作,这都是相同的事情)。您可能还更改了它指向的地址,例如忘记在分配时取消引用它(类似于*g = ...;变为g = ...;);这个特殊的错误不太可能与结构,但你永远不会知道......

因此,当您遇到分段错误时,始终会仔细检查有问题的语句中涉及的所有指针。在这种情况下,g是唯一涉及的指针(参数和字段numberNode都是非指针变量),因此g是可疑部分。

您没有告诉我们您如何调用初始化函数,但在这种情况下,代码非常简单,一旦您查看g initGraph()参数的位置,原因应该很明显来自,以及它在进入initGraph()时的价值(和地址)。是g分配了吗? g是否指向足够大的内存块来保存整个结构?是否已初始化任何相关字段(例如,在指向本身包含指针的结构的指针的情况下),并且在问题陈述之前的值是否合理?

如果您仍然不确定,请通过调试器或在printf("&g=(%p)",g);的顶部添加initGraph()等内容来查看该指针的地址和值。无效指针有一种从实际内存地址的噪声中脱颖而出的趋势。

答案 1 :(得分:0)

来自main()的来电必须如下:

graph g;
initGraph(1, 1, &g);

或者像这样:

graph *g = malloc( sizeof(graph) );
initGraph(1, 1, g);

编辑:

在评论中有一个多方面的问题,关于我如何解释OP查询中未显示的代码中存在错误。

让我们看看函数的开头:

void initGraph(int numberNode, int numberArc, graph *g) {
    int i, j;
    g->numberNode = numberNode;
}

错误:

Program received signal SIGSEGV, Segmentation fault.
0x00000000004009a3 in initGraph (numberNode=15, numberArc=17, g=0x1) at src/topologicGraphOp.c:45
45          g->numberNode = numberNode;

错误提及行45我在评论中被问及如何知道行45的位置。但是,我立即删除了问题,因为在行号错误附近显示行内容,所以我们可以在提到的代码中找到该行。

45行的代码足够简单,仅当指针g被引用错误的内存时才会导致错误。

使用前,此函数不会修改指针g。此函数假定函数参数g指向的有效内存。

因此,使用错误的参数指针调用函数。所以我只是提出了正确初始化变量的有效和典型方法,并用这样的参数调用这样的函数。