我在这里需要一些帮助,但通过搜索找不到任何相关的内容。
因此,我正在编写一个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算法来解决这个问题。这就是为什么我们必须创建一个矩阵来存储边的长度的原因。
另外,使用调试器,我正在逐步执行它。
根据未显示的所有代码和输入,我看到一些问题或潜在问题:
该行:
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发生并像您所经历的那样随机崩溃。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句