【问题标题】:Calling free() on a variable initialised by strdup still results in memory leak在由 strdup 初始化的变量上调用 free() 仍然会导致内存泄漏
【发布时间】:2022-11-29 14:35:17
【问题描述】:

我有以下代码:

static const char * path[2];


int main(int argc, char *argv[]) {
    // validate argument

    char * temp = dirname(dirname(strdup(argv[optind])));
    path[0] = temp
    path[1] = NULL;

    // do stuff

    free(temp);
    return 0;
}

我知道 strdup 分配需要释放的内存以避免内存泄漏。我尝试在从函数返回之前执行此操作,但泄漏仍然存在。

Valgrind 输出:

$ valgrind --leak-check=full -s ./tstprog meta_schema.schema 
==36849== Memcheck, a memory error detector
==36849== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==36849== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==36849== Command: ./tstprog meta_schema.schema
==36849== 
==36849== Invalid free() / delete / delete[] / realloc()
==36849==    at 0x484827F: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==36849==    by 0x11577A: main (tstprog.c:134)
==36849==  Address 0x4a42ae1 is 0 bytes inside data symbol "dot.0"
==36849== 
==36849== 
==36849== HEAP SUMMARY:
==36849==     in use at exit: 19 bytes in 1 blocks
==36849==   total heap usage: 255 allocs, 255 frees, 64,111 bytes allocated
==36849== 
==36849== 19 bytes in 1 blocks are definitely lost in loss record 1 of 1
==36849==    at 0x4845899: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==36849==    by 0x49240CF: strdup (in /usr/lib/libc.so.6)
==36849==    by 0x1155C1: main (tstprog.c:108)
==36849== 
==36849== LEAK SUMMARY:
==36849==    definitely lost: 19 bytes in 1 blocks
==36849==    indirectly lost: 0 bytes in 0 blocks
==36849==      possibly lost: 0 bytes in 0 blocks
==36849==    still reachable: 0 bytes in 0 blocks
==36849==         suppressed: 0 bytes in 0 blocks
==36849== 
==36849== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
==36849== 
==36849== 1 errors in context 1 of 2:
==36849== Invalid free() / delete / delete[] / realloc()
==36849==    at 0x484827F: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==36849==    by 0x11577A: main (tstprog.c:134)
==36849==  Address 0x4a42ae1 is 0 bytes inside data symbol "dot.0"
==36849== 
==36849== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

我还查看了this post,他们在拨打 free(who->name) 时似乎做同样的事情。

我错过了什么?

【问题讨论】:

  • 这个程序才不是在strdup()返回的指针上调用free()。它在 dirname(dirname(strdup(...))) 返回的一个上调用 free()。没有特别的理由期望 dirname() 返回它的参数。事实上,its docs 特别指出它“可能会返回 [a] 指针 [] 到静态分配的内存,该内存可能会被后续调用覆盖。”来自 valgrind 的“无效免费”错误表明您的 dirname() 确实如此。
  • 请注意,这也意味着像您演示的那样链接 dirname() 调用可能不安全。

标签: c memory-leaks valgrind strdup


【解决方案1】:

引用自 dirname 手册页

   Both dirname() and basename() return pointers to null-terminated strings.  
   (Do not pass these pointers to free(3).)

您没有释放 strdup 结果(确实可以)。您正在释放 dirname 结果。你不能。

【讨论】:

    猜你喜欢
    • 2016-01-18
    • 2021-03-23
    • 1970-01-01
    • 2019-11-24
    • 2011-02-01
    • 2021-09-16
    • 2015-04-17
    • 2020-05-11
    • 1970-01-01
    相关资源
    最近更新 更多