我的代码有问题。 它按预期工作,除了它最终得到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 ?? ()
答案 0 :(得分:1)
如果gdb
无法找到堆栈跟踪,则意味着您的代码在堆栈上写得如此彻底,以至于普通C运行时和gdb
都无法找到有关函数应该位于何处的信息返回堆栈。
或者,换句话说,你有一个(主要的)堆栈溢出。
某处,您的代码正在写出数组的边界。很遗憾,发布的代码引用了全局变量pos
和pac
,但是传递(未使用)变量postas
和pachet
。它表明您显示的代码不是您正在执行的代码。但是,假设pos
和pac
拼写与postas
和pachet
的拼写相同,那么可能是您错误处理了对distribuie()
的调用功能。 (如果,如评论所示,pos
和pac
确实是全局变量,那么为什么函数会通过postas
和pachet
?)
您收到任何编译警告吗?您是否启用了编译警告?如果你有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]
如果添加所有边界检查,它可能会运行。