double free or corruption
先看main.c代码:
#include <stdio.h>
#include <malloc.h>
#define DEBUG() printf("%s:%d\n", __FILE__, __LINE__); fflush(stdout);
int main(void)
{
void* p = malloc(100);
DEBUG();
void* p2 = malloc(114);
DEBUG();
realloc(p, 200);
DEBUG();
realloc(p, 300);
DEBUG();
return 0;
}
编译:
gcc main.c -o main && ./main
运行后会报错:
…………
*** glibc detected *** ./main: double free or corruption (!prev): 0x09211008 ***
======= Backtrace: =========
/lib/libc.so.6[0x7cd5a5]
/lib/libc.so.6[0x7cf7bc]
/lib/libc.so.6(realloc+0xe6)[0x7d0386]
./main[0x80484ec]
/lib/libc.so.6(__libc_start_main+0xdc)[0x779e9c]
./main[0x8048381]
======= Memory map: ========
00746000-00760000 r-xp 00000000 08:02 4196833 /lib/ld-2.5.so
00760000-00761000 r-xp 00019000 08:02 4196833 /lib/ld-2.5.so
…………
各种百思不得其解啊... 各种百度各种头疼后,突然顿悟,原来是realloc的原因。前几天看realloc的原型时,把
extern void *realloc(void *mem_address, unsigned int newsize);
看错成:
extern void realloc(void *mem_address, unsigned int newsize);
结果导致找了好久的错。
解决方法:
realloc(p, 200);
这一行应该改为
p = realloc(p, 200);
也就是说,malloc(114)使得原有的malloc后面的块不足以分配(200-100)大小的内存,于是realloc找到了一块新的内存,
把原来的内存数据搬运到新的内存中,原内存在realloc内被释放掉了,而当运行第二次的realloc时,
realloc内部再次进行 "找新内存 → 搬家 → free原内存” 的过程,因此出现了二次free的情况。
类似的情况:
char* a = NULL;
char* b = NULL;
a = (char*)malloc(100);
b = a;
free(a);
free(b); //这行出问题了,因为a指针指向的地址已经被free掉,而再次free(b)的话就会出double free的问题。