我需要一些帮助,我找不到任何与搜索有关的内容。
所以我正在编写一个C程序,并且发生了一些奇怪的事情。当我正常运行时我的程序崩溃,但是当我调试它时,它运行正常。我不知道发生了什么。
这是一项任务,应该在星期三到期,所以我吓坏了一点。
(我正在使用CodeBlocks IDE,如果有任何帮助的话。)
编辑: 很抱歉没有从头开始发布,我认为问题可能是我使用调试器错误或必须更改调试器设置(如果这甚至可能)。 这是接缝导致问题的功能:
double **makeMatrix(struct graph *head, char **nodes)
{
double **tmpMatrix=NULL;
int i=0, j=0;
struct graph *tmp=NULL;
if(nodes==NULL || head==NULL)
return NULL;
for(i=0; nodes[i] != NULL; i++);
tmpMatrix=calloc(i+1, sizeof(double*));
if(NULL==tmpMatrix)
{
printf("No Memory!");
return NULL;
}
for(j=0; j<i; j++)
{
tmpMatrix[j]=calloc(i+1, sizeof(double*));
if(NULL==tmpMatrix[j])
{
printf("No Memory!");
return NULL;
}
tmpMatrix[j][i] = -INF;
}
for(i=0; tmpMatrix[i] != NULL; i++)
{
for(j=0; tmpMatrix[i][j] != -INF; j++)
{
tmpMatrix[i][j] = INF;
}
}
for(tmp=head; tmp->fromNode >=0; tmp= tmp->next)
{
tmpMatrix[tmp->fromNode][tmp->toNode] = tmp->length;
printf("%f\n", tmpMatrix[tmp->fromNode][tmp->toNode] );
}
return tmpMatrix;
}
该任务是关于编写一个能够读取节点和图形以计算短路径的程序。哪里有Dijkstra算法来解决这个问题。这就是为什么我们必须创建一个矩阵,我们存储边长。
此外,使用调试器,我一步一步地执行它。
答案 0 :(得分:1)
根据您未显示的所有代码和输入,我发现了一些问题或潜在问题:
该行:
tmpMatrix[j]=calloc(i+1, sizeof(double*));
应该是:
tmpMatrix[j]=calloc(i+1, sizeof(double));
如果sizeof(double*) == 8
你可能是偶然的,但最好是真正正确的
在第一个for
循环中,您似乎在计算nodes
数组的大小。在这种情况下我不理解节点的使用,因为它没有在函数的其他地方使用。更好的函数签名是传递所需数组的大小。确保nodes
正确NULL
已被终止,否则您将遇到问题。我还会添加另一个变量来使数组大小显式,因为您稍后会重用i
,例如:
int arraySize = 0;
...
for (i = 0; nodes[i] != NULL; ++i);
arraySize = i;
tmpMatrix = calloc(arraySize + 1, sizeof(double*));
要将tmpMatrix
设置为INF
,最好使用显式数组索引,例如:
for (i = 0; i < arraySize; ++i)
{
for (j = 0; j < arraySize; ++j)
{
tmpMatrix[i][j] = INF;
}
}
这使您更清楚自己正在做什么,而且更不容易出错。
您应该在最后一个循环中明确检查NULL
指针:
for (tmp = head; tmp->fromNode >= 0; tmp = tmp->next)
如果未正确设置链接列表,则tmp
可能会变为NULL
,您将取消引用它,从而导致未定义的行为。只需在循环中添加一个检查,如:
for (tmp = head; tmp != NULL && tmp->fromNode >= 0; tmp = tmp->next)
您应该在上一个循环中检查tmpMatrix
的有效数组索引:
tmpMatrix[tmp->fromNode][tmp->toNode] = tmp->length;
如果tmp->fromNode
或tmp->toNode
是无效的数组索引,您将溢出/下溢数组并导致UB。即使你“知道”这些值应该是正确的,但是为了以下情况添加支票会更安全:
if (tmp->fromNode >= 0 && tmp->fromNode < arraySize &&
tmp->toNode >= 0 && tmp->toNode < arraySize)
{
...
}
很多这些都属于“防御性编程”类别。是的,nodes
和head
应该是NULL终止并且具有正确的索引,但是可能在某处有另一个错误而它们没有,或者收到了无效的输入,或者一个杂散的宇宙射线翻了一下记忆细胞。通过更仔细地检查您的输入,您可以防止UB发生并像您经历的那样随意地撞击您。