【发布时间】: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