gib*_*son 3 c gdb segmentation-fault
(更新:问题解决了.这一切都归结为我的一个愚蠢的错字,导致我写错记忆的部分,这反过来导致一些指针指向某个不受限制的地方.)
所以,我正在学习一门涉及一些编程的课程,而且我们基本上已经被抛入了C池的深处.我以前用其他语言编程,所以它并不是全新的,但我没有一套可靠的工具来调试我的代码,当众所周知的屎袭击了粉丝.
基本上,我有以下几点
int nParticles = 32;
int nSteps = 10000;
double u[nParticles], v[nParticles];
for (i = 0; i < nSteps; i++) {
...
for (j = 0; j < nParticles; j++) {
u[j] = 0.001 * v[j];
}
...
}
Run Code Online (Sandbox Code Playgroud)
作为一个更大的程序的一部分,我正在得到分段错误.为了查明问题,我添加了一堆
printf("foo\n");
Run Code Online (Sandbox Code Playgroud)
并且最终我发现我已经迈出了步骤i = 209,并且j = 31在发生分段故障之前出现了粒子.
有点谷歌搜索后,我意识到有一个名为工具gdb,并与额外的printf在那里,但在进行bt中gdb告诉我,现在是printf该段错误.但请记住,我在添加诊断printfs之前也得到了段错误.
这对我来说没什么意义.我该如何从这里开始?
更新:
valgrind 给我以下
==18267== Invalid read of size 8
==18267== at 0x400EA6: main (in [path redacted])
==18267== Address 0x7ff001000 is not stack'd, malloc'd or (recently) free'd
==18267==
==18267==
==18267== Process terminating with default action of signal 11 (SIGSEGV)
==18267== Access not within mapped region at address 0x7FF001000
==18267== at 0x400EA6: main (in [path redacted])
==18267== If you believe this happened as a result of a stack
==18267== overflow in your program's main thread (unlikely but
==18267== possible), you can try to increase the size of the
==18267== main thread stack using the --main-stacksize= flag.
==18267== The main thread stack size used in this run was 10485760.
==18267==
==18267== HEAP SUMMARY:
==18267== in use at exit: 1,136 bytes in 2 blocks
==18267== total heap usage: 2 allocs, 0 frees, 1,136 bytes allocated
==18267==
==18267== LEAK SUMMARY:
==18267== definitely lost: 0 bytes in 0 blocks
==18267== indirectly lost: 0 bytes in 0 blocks
==18267== possibly lost: 0 bytes in 0 blocks
==18267== still reachable: 1,136 bytes in 2 blocks
==18267== suppressed: 0 bytes in 0 blocks
==18267== Rerun with --leak-check=full to see details of leaked memory
==18267==
==18267== For counts of detected and suppressed errors, rerun with: -v
==18267== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)
我不知道这意味着什么.
更新:
我试着评论最初导致段错误的数组赋值.当我这样做,但留下大部分诊断printfs时,我得到一个段错误i = 207.
更新:
问题解决了.在外部循环中(其中i是计数器,表示时间步长),我有几个内部循环(所有这些循环都j作为计数器重复使用,迭代一堆粒子).在其中一个内部循环中(虽然不是segfaulted的那个),我偶然会将值分配给E[i]where E数组的nParticles大小,所以我的运行方式超出了界限.修复这个会阻止段错误的发生.
所以,这一切都归结为我自己的愚蠢错字.
更新:
我和我哥哥说话,他以一种至少满足我对情况的有限理解的方式解释了这个问题.
通过意外地写出E超出该数组末尾的东西,我可能覆盖了与我的其他数组相关的指针,然后当我去访问那些其他数组时,我尝试访问不是我的内存,并且我得到了段错误.
非常感谢你帮助我并忍受我缺乏知识!
这个评论太长了,但不是一个完整的答案.如果没有看到最小的代码示例,就无法判断为什么程序会死掉.
printf 通常是段错误,原因有以下三种:其中之一
你正在传递一个它无法访问的参数(例如char *,它没有指向正确分配的包含零终止字符串的内存),或者
由于过多的递归,你已经耗尽了堆栈空间(堆栈溢出),或者
你通过编写动态内存分配来破坏堆.
我的建议是:
使用该-Wall选项编译您的程序.修复每个警告,并了解警告发生的原因而不是隐藏问题.编译-Wall是一个很好的习惯,并发现大量的错误.
下载valgrind并运行您的程序valgrind.这将抓住很多东西.
学会使用gdb.这里的教程.
评论或#if排除程序的大块,直到你找到最简单的错误情况.重新添加位并找出问题所在.