C 为什么添加printf(“a”)会使代码运行,而删除它会使代码崩溃

C 为什么添加printf(“a”)会使代码运行,而删除它会使代码崩溃,c,runtime-error,C,Runtime Error,我有以下C代码: while(tempNode!=NULL) { int pos = pathNodesCount-1-i; pathNodes[pos] = tempNode; //printf("A"); euclidianLength += tempNode->g; i = i+1; tempNode = tempNode->parent; } 如果我将printfA语句注释掉,然后编译并运行我的代码,我将得到一个应用程序停止运

我有以下C代码:

while(tempNode!=NULL) {
    int pos = pathNodesCount-1-i;
    pathNodes[pos] = tempNode;
    //printf("A");
    euclidianLength += tempNode->g;
    i = i+1;
    tempNode = tempNode->parent;
}
如果我将printfA语句注释掉,然后编译并运行我的代码,我将得到一个应用程序停止运行Windows错误。如果我取消对printfA行的注释,重新编译并运行,那么应用程序将一直运行到它的末尾,并将A打印到控制台。为什么?

环境是:

Windows 7 32位 MinGW32 20120426,我添加了MSys 1.0 C/CPP的eclipsejuno ==更新

我跟踪了我的错误。我不会发布确切的代码,因为它太长了,但这是一个创建字符数组的例子,然后在错误的索引中添加字符。大概是这样的:

int otherCrap() {
    char* c = malloc(10*sizeof(char));
    int i = 0;
    for(i = 0; i<13; i++) {
        c[i]='a';
    }
    c[15] = '\0';
    printf("A");
    printf(c);

    return 0;
}

修复了这个问题,使字符仅放置在数组中现有索引处,并将“\0”字符作为数组中的最后一个元素。然而,我仍然不清楚为什么当代码不好时,在打印字符数组之前添加printf'a'不会导致运行时错误。从目前为止收到的答案中,我了解到这属于未定义的行为。

可能是因为代码中的某些错误导致未定义的行为。然后让代码在printf存在的情况下工作就可以了


倒计时的索引逻辑看起来很可怕;验证它是否正确。在使用索引之前打印索引,并与pathNodes数组的已知大小(如果有)进行比较。小心索引变为负值或超出pathNodes的容量。

可能是因为代码中的某些错误导致未定义的行为。然后让代码在printf存在的情况下工作就可以了


倒计时的索引逻辑看起来很可怕;验证它是否正确。在使用索引之前打印索引,并与pathNodes数组的已知大小(如果有)进行比较。当心索引变为负值或超出pathNodes的容量。

一种猜测-堆栈损坏。您确定pos具有正确的值吗?如果您的程序是多线程的,则可能是一种争用条件,由于printf调用中的额外时间而得到缓解。否则可能是堆栈问题。您是否在调试器中运行以确保索引未超出范围?这是一种猜测堆栈损坏。您确定pos具有正确的值吗?如果您的程序是多线程的,则可能是一种争用条件,由于printf调用中的额外时间而得到缓解。否则可能是堆栈问题。你有没有在调试器中运行以确保索引没有超出范围?嗯,这就是我试图做的:在可怕的循环中打印索引,因为我还认为它发生了一些不好的事情。一旦我添加了printf%d\n,什么变量,我注意到一切都正常,索引也正常。然后我将printf缩减为printfA,它仍然有效,我不明白为什么…@ShivanDragon-索引也是我的猜测。好的,可以再次运行测试并关注tempNode=tempNode->parent;。另外,由于这个问题很容易重现,为什么不使用调试器来捕获这个bug呢?@Kiril Kirov:谢谢你的输入。我很想使用调试器,但我不知道如何使用。是的,这很愚蠢,我是个笨蛋,对不起。我尝试过用Eclipse进行调试,但我注意到只有当代码运行到最后时,它才起作用。如果代码在应用程序中意外停止,调试器将永远不会在我的断点处停止。但这是另一个问题。无论如何,我已经发现了我的错误,并将其作为问题的更新添加。@ShivanDragon-这没什么大不了的,你不能使用调试器。一开始,这有点奇怪,但知道如何使用调试器是无价的,花一些时间学习如何使用调试器是值得的。@KirilKirov我完全同意你的观点,并打算下一步这样做。这只是我学习C语言的第五天。无论如何,我希望我在Java的经验能对学习有所帮助,但事实并非如此,C语言做某些事情的方式是完全不同的。这就是我试图做的:在可怕的循环中打印索引,因为我也认为它发生了一些不好的事情。一旦我添加了printf%d\n,什么变量,我注意到一切都正常,索引也正常。然后我将printf缩减为printfA,它仍然有效,我不明白为什么…@ShivanDragon-索引也是我的猜测。好的,可以再次运行测试并关注tempNode=tempNode->parent;。另外,由于这个问题很容易重现,为什么不使用调试器来捕获这个bug呢?@Kiril Kirov:谢谢你的输入。我很想使用调试器,但我不知道如何使用。是的,这很愚蠢,我是个笨蛋,对不起。我尝试过用Eclipse进行调试,但我注意到只有当代码运行到最后时,它才起作用。如果代码在应用程序中意外停止,调试器将永远不会在我的断点处停止。但这是另一个问题。无论如何,我已经发现了我的错误,并将其作为更新添加到questi中
打开。@ShivanDragon-没什么大不了的,你不能使用调试器。一开始,这有点奇怪,但知道如何使用调试器是无价的,花一些时间学习如何使用调试器是值得的。@KirilKirov我完全同意你的观点,并打算下一步这样做。这只是我学习C语言的第五天。无论如何,我希望我在Java中的经验能对学习有所帮助,但事实并非如此,C语言做某些事情的方式是完全不同的。