【问题标题】:C free does not work inside nested mallocs and a reallocC free 在嵌套的 malloc 和 realloc 中不起作用
【发布时间】:2019-03-07 19:25:33
【问题描述】:

我有以下代码:

#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[..] 它会失败。这对我来说很奇怪。我做错了什么?

【问题讨论】:

  • entries 在调用realloc 后(在某些情况下)无效。你应该释放hz。但在您验证realloc 是否成功之前。
  • 调用realloc的正确方法是将结果保存在一个临时变量中并检查它是否成功。如果确实成功,则将 temp 重新分配给原始变量。如果 realloc 失败,您的原始变量仍指向原始内存。有关详细信息,请参阅此答案:stackoverflow.com/a/42079347/1212725

标签: c malloc realloc


【解决方案1】:

如果一切顺利,您应该会看到realloc 是malloc,然后是memcpy,然后是free。因此,特别是如果 realloc 成功,当您执行 free 时,您的 entries 分配早已不复存在。

【讨论】:

    【解决方案2】:

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

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

    执行(char*) malloc(1) 失败的原因可能是因为它在上次分配之后分配了内存。如果没有该分配,realloc() 能够将原始分配扩展到该空间。同样,调用printf() 可能会进行一些内部内存分配,这会阻止它增加分配。其他小改动也会影响内存布局。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-17
      • 2021-03-28
      • 1970-01-01
      • 2012-07-13
      • 2019-09-19
      • 2012-02-22
      • 2021-12-11
      • 2014-04-27
      相关资源
      最近更新 更多