代码不起作用。但是在调试的时候

时间:2015-06-20 17:58:59

标签: c codeblocks

我需要一些帮助,我找不到任何与搜索有关的内容。

所以我正在编写一个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算法来解决这个问题。这就是为什么我们必须创建一个矩阵,我们存储边长。

此外,使用调试器,我一步一步地执行它。

1 个答案:

答案 0 :(得分:1)

根据您未显示的所有代码和输入,我发现了一些问题或潜在问题:

  1. 该行:

    tmpMatrix[j]=calloc(i+1, sizeof(double*));
    

    应该是:

    tmpMatrix[j]=calloc(i+1, sizeof(double));
    

    如果sizeof(double*) == 8你可能是偶然的,但最好是真正正确的

  2. 在第一个for循环中,您似乎在计算nodes数组的大小。在这种情况下我不理解节点的使用,因为它没有在函数的其他地方使用。更好的函数签名是传递所需数组的大小。确保nodes正确NULL已被终止,否则您将遇到问题。我还会添加另一个变量来使数组大小显式,因为您稍后会重用i,例如:

    int arraySize = 0;
    ...
    for (i = 0; nodes[i] != NULL; ++i);
    arraySize = i;
    tmpMatrix = calloc(arraySize + 1, sizeof(double*));
    
  3. 要将tmpMatrix设置为INF,最好使用显式数组索引,例如:

    for (i = 0; i < arraySize; ++i)
    {
        for (j = 0; j < arraySize; ++j)
        {
            tmpMatrix[i][j] = INF;
        }
    }
    

    这使您更清楚自己正在做什么,而且更不容易出错。

  4. 您应该在最后一个循环中明确检查NULL指针:

    for (tmp = head; tmp->fromNode >= 0; tmp = tmp->next)
    

    如果未正确设置链接列表,则tmp可能会变为NULL,您将取消引用它,从而导致未定义的行为。只需在循环中添加一个检查,如:

    for (tmp = head; tmp != NULL && tmp->fromNode >= 0; tmp = tmp->next)
    
  5. 您应该在上一个循环中检查tmpMatrix的有效数组索引:

    tmpMatrix[tmp->fromNode][tmp->toNode] = tmp->length;
    

    如果tmp->fromNodetmp->toNode是无效的数组索引,您将溢出/下溢数组并导致UB。即使你“知道”这些值应该是正确的,但是为了以下情况添加支票会更安全:

    if (tmp->fromNode >= 0 && tmp->fromNode < arraySize &&
        tmp->toNode   >= 0 && tmp->toNode   < arraySize) 
    {
       ...
    }
    
  6. 很多这些都属于“防御性编程”类别。是的,nodeshead应该是NULL终止并且具有正确的索引,但是可能在某处有另一个错误而它们没有,或者收到了无效的输入,或者一个杂散的宇宙射线翻了一下记忆细胞。通过更仔细地检查您的输入,您可以防止UB发生并像您经历的那样随意地撞击您。