我有以下代码:
#include <stdlib.h>
#define STRING_LENGTH 50
typedef struct entry {
char name[STRING_LENGTH];
} datum;
int main(void) {
datum *entries = NULL;
entries = (datum*) malloc(sizeof(datum)) ;
char *buffer_ = (char*) malloc(1);
free(buffer_);
void *hz = realloc(entries , 2 * sizeof(datum));
free(entries);
return 0;
}
但是,如果我编译此代码并运行二进制文件,则会出现以下错误:
*** Error in `./a.out': double free or corruption (fasttop): 0x00005572b0381010 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x70bfb)[0x7ff4b3842bfb]
/lib/x86_64-linux-gnu/libc.so.6(+0x76fc6)[0x7ff4b3848fc6]
/lib/x86_64-linux-gnu/libc.so.6(+0x7780e)[0x7ff4b384980e]
./a.out(+0x799)[0x5572af4ca799]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7ff4b37f22e1]
./a.out(+0x63a)[0x5572af4ca63a]
======= Memory map: ========
5572af4ca000-5572af4cb000 r-xp 00000000 00:29 13267238517 a.out
5572af6ca000-5572af6cb000 r--p 00000000 00:29 13267238517 a.out
5572af6cb000-5572af6cc000 rw-p 00001000 00:29 13267238517 a.out
5572b0381000-5572b03a2000 rw-p 00000000 00:00 0 [heap]
7ff4ac000000-7ff4ac021000 rw-p 00000000 00:00 0
7ff4ac021000-7ff4b0000000 ---p 00000000 00:00 0
7ff4b35bb000-7ff4b35d1000 r-xp 00000000 08:01 6815758 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ff4b35d1000-7ff4b37d0000 ---p 00016000 08:01 6815758 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ff4b37d0000-7ff4b37d1000 r--p 00015000 08:01 6815758 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ff4b37d1000-7ff4b37d2000 rw-p 00016000 08:01 6815758 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ff4b37d2000-7ff4b3967000 r-xp 00000000 08:01 6816376 /lib/x86_64-linux-gnu/libc-2.24.so
7ff4b3967000-7ff4b3b67000 ---p 00195000 08:01 6816376 /lib/x86_64-linux-gnu/libc-2.24.so
7ff4b3b67000-7ff4b3b6b000 r--p 00195000 08:01 6816376 /lib/x86_64-linux-gnu/libc-2.24.so
7ff4b3b6b000-7ff4b3b6d000 rw-p 00199000 08:01 6816376 /lib/x86_64-linux-gnu/libc-2.24.so
7ff4b3b6d000-7ff4b3b71000 rw-p 00000000 00:00 0
7ff4b3b71000-7ff4b3b94000 r-xp 00000000 08:01 6816210 /lib/x86_64-linux-gnu/ld-2.24.so
7ff4b3d6a000-7ff4b3d6c000 rw-p 00000000 00:00 0
7ff4b3d93000-7ff4b3d94000 rw-p 00000000 00:00 0
7ff4b3d94000-7ff4b3d95000 r--p 00023000 08:01 6816210 /lib/x86_64-linux-gnu/ld-2.24.so
7ff4b3d95000-7ff4b3d96000 rw-p 00024000 08:01 6816210 /lib/x86_64-linux-gnu/ld-2.24.so
7ff4b3d96000-7ff4b3d97000 rw-p 00000000 00:00 0
7ffd1bf9f000-7ffd1bfc0000 rw-p 00000000 00:00 0 [stack]
7ffd1bfdd000-7ffd1bfdf000 r--p 00000000 00:00 0 [vvar]
7ffd1bfdf000-7ffd1bfe1000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
如果我删除行(char *buffer_ = (char*) malloc(1);
)和下一行free(buffer_);
,则二进制文件可以正常工作。如果用printf("Hello");
替换相同的两行,则会出现相同的错误。如果我用双名替换char name[..]
可以正常工作,如果我再次用char name[..]
替换long double
则失败。这对我来说很奇怪。我在做什么错了?
答案 0 :(得分:5)
如果一切顺利,您应该将realloc
视为malloc
,然后是memcpy
,然后是free
。因此,特别是如果realloc
成功了,那么当您执行entries
时,您的free
分配就已经消失了。
答案 1 :(得分:1)
您似乎假设realloc()
将重用entries
指向的内存。尽管有时它可以重用现有分配(尤其是当您重新分配为较小的大小时),所以hz == entries
不一定是这种情况,并且您永远都不要假设它。
就您而言,entries
所指向的内存已由realloc()
释放,并且唯一有效的内存已由hz
指向。
执行(char*) malloc(1)
时失败的原因可能是因为该操作在先前的分配之后分配了内存。没有该分配,realloc()
便能够将原始分配扩展到该空间。同样,调用printf()
可能会进行一些内部内存分配,这会阻止它扩大分配。其他较小的更改也会影响内存布局。