分段故障.在数组元素赋值中,但现在在printf中

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在那里,但在进行btgdb告诉我,现在是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超出该数组末尾的东西,我可能覆盖了与我的其他数组相关的指针,然后当我去访问那些其他数组时,我尝试访问不是我的内存,并且我得到了段错误.

非常感谢你帮助我并忍受我缺乏知识!

abl*_*igh 5

这个评论太长了,但不是一个完整的答案.如果没有看到最小的代码示例,就无法判断为什么程序会死掉.

printf 通常是段错误,原因有以下三种:其中之一

  1. 你正在传递一个它无法访问的参数(例如char *,它没有指向正确分配的包含零终止字符串的内存),或者

  2. 由于过多的递归,你已经耗尽了堆栈空间(堆栈溢出),或者

  3. 你通过编写动态内存分配来破坏堆.

我的建议是:

  1. 使用该-Wall选项编译您的程序.修复每个警告,并了解警告发生的原因而不是隐藏问题.编译-Wall是一个很好的习惯,并发现大量的错误.

  2. 下载valgrind并运行您的程序valgrind.这将抓住很多东西.

  3. 学会使用gdb.这里的教程.

  4. 评论或#if排除程序的大块,直到你找到最简单的错误情况.重新添加位并找出问题所在.