C free在嵌套的malloc和realloc中不起作用

时间:2019-03-07 19:25:33

标签: c malloc realloc

我有以下代码:

#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则失败。这对我来说很奇怪。我在做什么错了?

2 个答案:

答案 0 :(得分:5)

如果一切顺利,您应该将realloc视为malloc,然后是memcpy,然后是free。因此,特别是如果realloc成功了,那么当您执行entries时,您的free分配就已经消失了。

答案 1 :(得分:1)

您似乎假设realloc()将重用entries指向的内存。尽管有时它可以重用现有分配(尤其是当您重新分配为较小的大小时),所以hz == entries不一定是这种情况,并且您永远都不要假设它。

就您而言,entries所指向的内存已由realloc()释放,并且唯一有效的内存已由hz指向。

执行(char*) malloc(1)时失败的原因可能是因为该操作在先前的分配之后分配了内存。没有该分配,realloc()便能够将原始分配扩展到该空间。同样,调用printf()可能会进行一些内部内存分配,这会阻止它扩大分配。其他较小的更改也会影响内存布局。