【发布时间】:2022-01-21 10:28:46
【问题描述】:
我用下面的代码测试getenv返回的指针,如果不空闲,测试会导致内存泄漏。
#include <stdio.h>
#include <stdlib.h>
void demo() {
const char *home = getenv("HOME");
printf("%s\n", home);
}
int main() {
demo();
return 0;
}
我使用 Valgrind 来检测内存泄漏:
$ gcc main.c -o main
$ valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all ./main
结果如下:
==134679== Memcheck, a memory error detector
==134679== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==134679== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==134679== Command: ./demo
==134679==
/home/aszswaz
==134679==
==134679== HEAP SUMMARY:
==134679== in use at exit: 0 bytes in 0 blocks
==134679== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==134679==
==134679== All heap blocks were freed -- no leaks are possible
==134679==
==134679== For lists of detected and suppressed errors, rerun with: -s
==134679== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
表示申请了一块内存,回收了一块内存。为什么getenv得到的指针会被自动回收?
如果我在代码中添加free((void *)home),会不会影响全局环境变量?
【问题讨论】:
-
为什么你认为从getenv得到的指针实际上指向的是堆上分配的内存?
-
不要将指针与其指向的内容混淆。指针本身有自动存储,它指向的对象是一个字符串,不是你管理的
-
这将具体到如何指定
getenv(),以及实现者如何选择满足该规范。在 C++ 中,任何具有静态存储持续时间的对象都会在main()正常返回后被销毁,其构造顺序与它们的构造顺序相反。因此,实现getenv()以提供您在 C++ 中描述的行为肯定是可行的。 (不对它是否用 C++ 实现发表任何评论 - 只是,任何语言的可行性都表明它在技术上总体上是可行的)。 -
你永远不应该
free一个由getenv获得的指针,因为它没有指向malloc返回的内存。有问题的内存块可能由printf分配和释放,而不是getenv。
标签: c memory-leaks environment-variables valgrind