我的目标是实现一个算法来检查图形是否是拓扑的。但是,这不是问题。在尝试使用给定数据初始化我的图形结构时,我得到了核心转储。
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我的图形指针。
答案 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
指向的有效内存。
因此,使用错误的参数指针调用函数。所以我只是提出了正确初始化变量的有效和典型方法,并用这样的参数调用这样的函数。