代码非常简单:
#include <vector>
int main() {
std::vector<int> v;
}
然后我用Valgrind构建并运行它:
g++ test.cc && valgrind ./a.out
==8511== Memcheck, a memory error detector
==8511== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==8511== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==8511== Command: ./a.out
==8511==
==8511==
==8511== HEAP SUMMARY:
==8511== in use at exit: 72,704 bytes in 1 blocks
==8511== total heap usage: 1 allocs, 0 frees, 72,704 bytes allocated
==8511==
==8511== LEAK SUMMARY:
==8511== definitely lost: 0 bytes in 0 blocks
==8511== indirectly lost: 0 bytes in 0 blocks
==8511== possibly lost: 0 bytes in 0 blocks
==8511== still reachable: 72,704 bytes in 1 blocks
==8511== suppressed: 0 bytes in 0 blocks
==8511== Rerun with --leak-check=full to see details of leaked memory
==8511==
==8511== For counts of detected and suppressed errors, rerun with: -v
==8511== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
问题是双重的:
(1)&#34;总堆使用量&#34;表示有1个alloc和0个free。我假设1 alloc是因为std :: vector实例需要堆中的内存块。没关系;但为什么在毁灭期间它没有释放记忆?
(2)并且,如果它没有释放它,为什么没有内存泄漏&#34; LEAK SUMMARY&#34;?
(3)顺便说一句,每行前==8511==
是什么意思? (不过,我可以在手册中查一查。你不必回答这个问题)
谢谢!
答案 0 :(得分:4)
C ++运行时仍在使用报告的内存。你不必担心它。关于这个问题,Valgrind的FAQ有an entry:
首先:放松,这可能不是一个错误,而是一个功能。许多C ++标准库的实现都使用自己的内存池分配器。许多被破坏对象的内存不会立即被释放并返回给操作系统,而是保存在池中以供以后重复使用。
答案 1 :(得分:2)
(1)正确实现的默认构造std::vector
没有分配。 Esp不是72k。尝试使用--leak-check=full --track-origins=yes
运行,也许它会显示分配的来源
(2)它说,看到:仍然可以到达。内存尚未泄漏,因为它仍然是一个指向它的句柄(例如:一个指针)。
(3)它是应用程序的进程ID。
答案 2 :(得分:1)
您所看到的72kb是由C ++运行时为其“紧急异常处理池”分配的。该池用于分配异常对象(例如bad_alloc
异常),即使malloc
不能再分配任何东西。我们在启动时进行了预分配,因此如果malloc
内存不足,我们仍然可以抛出bad_alloc
异常。
具体数字来自此代码:
// Allocate the arena - we could add a GLIBCXX_EH_ARENA_SIZE environment
// to make this tunable.
arena_size = (EMERGENCY_OBJ_SIZE * EMERGENCY_OBJ_COUNT
+ EMERGENCY_OBJ_COUNT * sizeof (__cxa_dependent_exception));
arena = (char *)malloc (arena_size);
较新版本的valgrind
知道此紧急EH池,并在进程退出之前立即调用一个特殊函数将其释放,以使您看不到in use at exit: 72,704 bytes in 1 blocks
。这样做是因为太多的人不了解仍在使用(并且仍然可以访问)的内存并不是泄漏,并且人们一直抱怨它。因此,现在valgrind释放了它,只是为了阻止人们抱怨。当不在valgrind下运行时,不会释放该池,因为这样做是不必要的(无论如何,该进程退出时,操作系统都会对其进行回收)。