1

我是 C 新手,在 Linux 中使用带有开关的 gcc4.4.6 进行编程gcc -g -std=c89 -Wall ...,并且在我的程序深处的许多函数中都遇到了这个错误,名为compute

*** glibc detected *** ./compute: corrupted double-linked list: 0x0000000001a770b0 ***
======= Backtrace: =========
/lib64/libc.so.6[0x366d475916]
/lib64/libc.so.6[0x366d4786a4]
./compute[0x406987]
./compute[0x407f0d]
./compute[0x408a41]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x366d41ecdd]
./compute[0x401769]
======= Memory map: ========
...

下面是一些伪代码(代码很长,这里只展示结构):

myPts = 100;
JDP = malloc( sizeof(double) * myPts);
if (JDP == NULL)
   exit(27);
...
if (testCondition == 1) { /* my execution enters this if stmt here */
   ...
   myPts = 200;
   free(JDP);
   JDP = malloc (sizeof(double) * myPts);
   if (JDP == NULL)
      exit(27);
   myFunction(JDP, ...); /* array JDP is populated here */
   ...
 } else {
    JDP[0]=0;
 }
 myOtherFunction(..., JDP, ...); /* array JDP is used here */
 free(JDP); /* this line produces error shown above */
 return 0;

使用 gdb 单步执行代码,此错误在代码的第二行产生:free(JDP). 执行是这样的,数组JDP被 malloc'ed 两次,它们之间有一个 free。这可能是错误的原因吗?我以前从未这样做过,希望我犯了一些简单的错误......

更新 1

只是想特别注意,使用 gdb 我确实通过第一个空闲和第二个 malloc 逐步执行代码,所以我知道代码通过了这些步骤。

如果上面的设计模式没有问题,还有哪些其他场景会导致free()这个错误?

4

2 回答 2

2

您显示的代码没有任何明显错误。特别是代码模式

x = malloc(n);
...
if (condition) {
    free(x); 
    x = malloc(m);
}
...
free(x);

本身并没有错。

您几乎可以肯定在您显示的代码中某处犯了一个简单的错误,这导致了内存损坏。幸运的是,有一个很好的工具可以自动发现此类错误:它被称为valgrind. 在这个工具下运行你的程序。修复它告诉您的第一个错误。重复,直到它告诉您没有进一步的错误。(通常只有第一个 valgrind 的投诉反映了您的代码中的一个真正的错误;所有后续的投诉“仅仅是”原始内存访问错误的后果。)

于 2012-11-10T02:58:24.237 回答
1

只要您在它们之间分别进行分配,两次释放变量就可以了。我怀疑问题在于您实际上并没有在它们之间进行分配-某些逻辑开关(if/else/while)正在阻止malloc发生,因此在free同一个指针上发生了两次。

于 2012-11-10T02:55:23.930 回答