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

C free does not work inside nested mallocs and a 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[..] 它有效,如果我再次用 long double 替换 char name[..] 它会失败。这对我来说很奇怪。我做错了什么?

如果一切顺利,您应该看到 reallocmalloc,然后是 memcpy,然后是 free。因此,特别是如果 realloc 成功,那么当您执行 free.

时,您的 entries 分配早就消失了

您似乎假设 realloc() 将重用 entries 指向的内存。虽然它有时可以重用现有分配(特别是当您重新分配到 更小的 大小时),因此 hz == entries,但情况不一定如此,您永远不应该假设它。

就你而言,entries指向的内存已经被realloc()释放,唯一有效的内存是hz指向的。

当您执行 (char*) malloc(1) 时它失败的原因可能是因为它在上一次分配之后分配了内存。没有那个分配,realloc() 能够将原始分配增加到那个 space。同样,调用 printf() 可能会进行一些内部内存分配,这会阻止它增加分配。其他小的变化也会影响内存布局。