释放内存问题导致我的c程序崩溃,但在调试时不会崩溃?

释放内存问题导致我的c程序崩溃,但在调试时不会崩溃?,c,debugging,memory,crash,valgrind,C,Debugging,Memory,Crash,Valgrind,我以前在使用这个程序时遇到过麻烦,因为它会分配大量内存。大多数问题我都解决了,但有一个问题我仍然有困难。当我在Eclipse中运行我的程序时,它编译得很好,但由于以下消息而崩溃 *** glibc detected *** /home/user/workspace/TTPrueba/Debug/TTPrueba: free(): invalid pointer: 0xb6bc0588 *** 当我和Valgrind一起运行时,它告诉我 ==31580== Process terminating

我以前在使用这个程序时遇到过麻烦,因为它会分配大量内存。大多数问题我都解决了,但有一个问题我仍然有困难。当我在Eclipse中运行我的程序时,它编译得很好,但由于以下消息而崩溃

*** glibc detected *** /home/user/workspace/TTPrueba/Debug/TTPrueba: free(): invalid pointer: 0xb6bc0588 ***
当我和Valgrind一起运行时,它告诉我

==31580== Process terminating with default action of signal 11 (SIGSEGV)
==31580==  Access not within mapped region at address 0x0
==31580==    at 0x804BEA3: termino (Menu.c:899)
==31580==    by 0x804BE05: computar_transformadas (Menu.c:840)

所以问题是,它试图释放一个无效的内存地址,但我在调试模式下一步一步地执行,程序从未崩溃!!!!:

你知道为什么会发生这样的事吗?为什么它在调试时工作而在运行时不工作?这是非常奇怪的行为

for(phi=0;phi<360;phi++){

      for(j=0;j<par.param1[phi][0];j++){


              for(o=0;o<(par.prueba[phi][j][1]-par.prueba[phi][j][0]);o++){//AQUI 849

                 free(par.pixels[phi][j][o]);//HERE IS LINE 899 WHERE IT ALWAYS CRASHES

                 if(o==(par.prueba[phi][j][1]-par.prueba[phi][j][0]-1))
                     free(par.pixels[phi][j]);

              }


          free(par.prueba[phi][j]);

      }

谢谢你的帮助

一个可能的原因是,调试器可能正在更改事物的内存布局,因此当内存损坏时,它恰好位于一个偏僻的地方


或者调试器可能会导致分配的内存归零,这在生产运行中可能不会发生。

这并不奇怪。例如,如果PAR.Pix[Pi] [j] [O]未初始化。它可以包含任何东西,在调试器环境中,你有不同的内存布局PAR。像素[PHI] [j] [O]可能变成0,所以自由没有崩溃。

< P>一个问题,我看到的是你免费PAR。像素[PHI] [j] [O],从0开始循环,然后访问PAR。像素[PH] [j](0),这只是免费的!p>

你也可以释放PAR。像素[PHI] [j],但是继续循环访问PAR。像素[PHI] [j],释放不再有效的指针。< /P>啊。这些可爱的动物并不罕见——它们生活在自然栖息地。看到漂亮的羽毛伪装图案了吗?那是什么?你看不见吗?嗯,是的。这就是你知道它在那里的方式。在调试器中内存可能为零,在你的程序中可能不是这样。尝试将mallocs更改为callocs。我在调试模式下一步一步地进行,程序永远不会崩溃!!!!-欢迎来到调试世界!您没有显示malloc代码…为什么ifo==。。。在第三个for循环中释放?或者使用调试器在断点处停止的隐式同步正在改变线程的计时交互。。。如果多线程不是多线程的,那么这不是问题所在。我认为一些统一化的值是问题所在。除了使用calloc确保指针最初设置为NULL,使任何错误地取消引用的尝试变得明显之外,出于同样的原因释放指针指向的内存后将指针设置为NULL也是一个好的做法。或者有时候在调试时,一个有毒的值,比如0xDeadBeefDeadBeefBeef,它会在错误消息/调试打印中突出显示。我该怎么做?例如,如果我做freepar.pixels[phi][j][o];我应该在事后做些什么吗?如果你从未初始化它,你就无法修复它。检查它是从哪里来的,它必须被分配一个结果,它是一个有效的免费候选者。问题:如果PAR。像素[PHI] [j] [O]是一个已签名的int,并且它持有的值大于32767,这将导致一个问题,同时释放内存。PAR。像素[PH] [j] [O]不应该是一个已签名的int,它应该是指针类型,假设它包含前一个malloc调用的返回值。这个值并不重要。我从来没有访问PAR。像素[PH] [j](0)在释放PAR。像素[PH] [j] [O] i访问PAR。PrueB[Pi] [j](0)。当我释放PAR.Pix[PHI] [j]时,我确定它是最后一个循环,这样下一个它就会出来,并且停止释放内存。