gdb,gcc或两者都存在严重错误,我不知道是什么。我创建了一个POC来在gcc (GCC) 4.6.1 20110819 (prerelease)
和GNU gdb (GDB) 7.3.50.20110908-cvs
上重现它 - 是的,这是CVS版本,因为我遇到了这个问题http://sourceware.org/bugzilla/show_bug.cgi?id=12435,但我也测试过GNU gdb (GDB) 7.3.1
并且行为相同。
现在到POC:https://gist.github.com/1211017可以在第33行看到问题
在我看来,*c->foos[i]
应评估第i行的地址,如第21行所示。但可执行文件崩溃,正如您在输出中看到的那样。
有谁知道出了什么问题? ASM级别或GCC内部的解释将受到欢迎。
附录:
*c->foos[i]
用于处理旧版本的gcc。dump_container
必须具有参数a container*
- 此功能不属于我的代码另外值得一提:*c->foos[i]
曾经工作过。
答案 0 :(得分:3)
通过有用的valgrind运行代码说:
==16066== Use of uninitialised value of size 8 ==16066== at 0x40061B: dump_container (bug.c:33) ==16066== by 0x400726: main (bug.c:49) ==16066== ==16066== Invalid read of size 4 ==16066== at 0x400620: dump_container (stdio2.h:105) ==16066== by 0x400726: main (bug.c:49) ==16066== Address 0x89485ed18949ed39 is not stack'd, malloc'd or (recently) free'd ==16066== ==16066== ==16066== Process terminating with default action of signal 11 (SIGSEGV) ==16066== General Protection Fault ==16066== at 0x400620: dump_container (stdio2.h:105) ==16066== by 0x400726: main (bug.c:49) ==16066==
我的猜测是你会在自己的代码中找到错误而不是编译器或调试器。
编辑或者,因为您希望我为您拼写,请将第33行更改为
printf("foo[%d]=%d at %p\n", i, (*c->foos)[i]->i, (void*) (*c->foos)[i]);
答案 1 :(得分:1)
我不明白* c-> foos [i]将如何工作,c->foos
给出一个指向数组的指针(一个指向一团的指针)(指针),根据第43行,在执行c->foos[i]
时,您无法访问数组的元素。 (*c->foos)[i]
应该有用......
答案 2 :(得分:0)
在我看来,* c-> foos [i]应该评估为第i个地址 foo,如第21行所示。
没有。如果这是你的意思,你应该使用&c->foos[i]
。你的版本取消引用第i个foo,很容易导致
但可执行文件崩溃,正如您在输出中看到的那样。