程序结束时的分段错误

时间:2014-12-07 16:24:23

标签: c debugging segmentation-fault

我的代码有问题。 它按预期工作,除了它最终得到Seg故障。

以下是代码:

void distribuie(int *nrP, pach *pachet, post *postas) { 

    int nrPos, k, i, j;
    nrPos = 0;
    for (k = 0; k < 18; k++)
        pos[k].nrPac = 0; 
    for (i = 0; i < *nrP; i++) {
        int distributed = 0;
        for (j = 0; j < nrPos; j++) 
            if (pac[i].idCar == pos[j].id) {
                pos[j].vec[pos[j].nrPac] = pac[i].id;
                pos[j].nrPac++;
                distributed = 1;
                break;
            }
        if (distributed == 0) {
            pos[nrPos].id = pac[i].idCar;
            pos[nrPos].vec[0] = pac[i].id;
            pos[nrPos].nrPac = 1;
            nrPos++;
        }
    }
    for (i = 0; i < nrPos; i++) {
        printf("%d %d ", pos[i].id, pos[i].nrPac);
        for (j = 0; j < pos[i].nrPac; j++)
            printf("%d ", pos[i].vec[j]);
        printf("\n");
    }

}

并在main()中调用此函数。

使用gdb运行会导致此错误:

Program received signal SIGSEGV, Segmentation fault.
0x00000001 in ?? ()

2 个答案:

答案 0 :(得分:1)

如果gdb无法找到堆栈跟踪,则意味着您的代码在堆栈上写得如此彻底,以至于普通C运行时和gdb都无法找到有关函数应该位于何处的信息返回堆栈。

或者,换句话说,你有一个(主要的)堆栈溢出。

某处,您的代码正在写出数组的边界。很遗憾,发布的代码引用了全局变量pospac,但是传递(未使用)变量postaspachet。它表明您显示的代码不是您正在执行的代码。但是,假设pospac拼写与postaspachet的拼写相同,那么可能是您错误处理了对distribuie()的调用功能。 (如果,如评论所示,pospac确实是全局变量,那么为什么函数会通过postaspachet?)

您收到任何编译警告吗?您是否启用了编译警告?如果你有GCC,那么代码是否可以用-Wall干净地编译?用-Wall -Wextra怎么样?如果您收到任何警告,请修复原因。请记住,在您职业生涯的这个阶段,C编译器很可能比您更了解C语言。

您可以通过在输入函数时打印键值(如*nrP)来帮助自己进行调试。如果这不是一个合理的价值,你知道从哪里开始寻找。您可能还要仔细查看该行的数据:

pos[j].vec[pos[j].nrPac] = pac[i].id;

那里有很多空间让事情误入歧途!

答案 1 :(得分:1)

我缺乏完全帮助你的信息:我不知道pos []数组的大小。 k <18的循环表明它是18个元素(但它可能更少;我根本不知道)。然后你开始处理* nrP小包,但是你没有检查你最多处理了18个小包。如果还有更多,则覆盖其他一些内存。然后你想要打印结果et voila,一个分段错误,意味着一些内存被破坏,被某人认为它是一个有效的pionter,但指针无效,并且...... bang - segfault。

因此for循环应该至少检查边界(假设为18):

for (i = 0; i < *nrP && i < 18; i++) {

同样地,pos结构显然有一个vec数组,但它的大小是未知的,并且通过相同的推理可以是18,可以更少或更多:

pos[j].vec[pos[j].nrPac]

如果添加所有边界检查,它可能会运行。