【发布时间】:2015-02-05 12:58:30
【问题描述】:
我正在编写一些关键任务代码,我必须确保它绝对没有内存泄漏。我编写了一个小函数,允许我在运行时检索内存使用情况,并在执行一些代码(应该无泄漏)之前和之后进行测量,以查看内存使用情况是否保持在同一水平。
在调试一段“泄漏”的代码时,我终于发现罪魁祸首是向量容器。
重现我所看到的最小代码如下:
vector<char*>* v = new vector<char*>();
int n = 1024*1024;
while (n--)
{
v->push_back(new char[256]()); // A
}
for (vector<char*>::iterator it=v->begin() ; it!=v->end() ; ++it )
{
delete[] (*it);
}
delete v;
如果您运行该代码(当然禁用编译器优化,-O0)并在最后放置一些陷阱以使程序不会退出(例如cin.ignore();),您会看到您的程序应该使用20Mb 左右的内存。
我想了解为什么会这样。有一行我用A 标记,如果你分配一个更大的字符数组,你会看到最后的“剩余”内存也更大。我不会将其称为泄漏本身,因为如果我分配和填充另一个 STL 容器,显然可以重用内存,但我仍然希望在代码完成时完全释放该内存。
有人能解释一下为什么这个内存还在被使用吗?我怎样才能真正“释放”它?
关于我的编译环境的一些细节:
Using clang++: Apple LLVM version 6.0 (clang-600.0.51) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix
Compiling with: g++ -std=c++11 -g -Wall -Wextra -Wpedantic -O0 main.cc -o main.out
【问题讨论】:
-
为什么要使用vector
而不是vector > !? -
我只是使用该 char* 来分配任意数量的内存。实际上,您可以在那里使用任何类型的类型,并且仍然会观察到这种行为。
-
您似乎期望内存管理器实际上会因为您释放它而从您的进程中释放内存,但这不是它通常的工作方式。无论如何,它只是虚拟内存,所以只要您的进程不使用它,它就不会占用任何 RAM。而且,正如您所说,如果您要求更多内存,则该内存将被重用。
-
@Deduplicator 您可以尝试使用 vector
* 运行代码,并以您喜欢的方式分配所有内容。你仍然会观察到这种行为。 -
在系统监视器等中查看内存使用情况绝对是检查泄漏的错误方法,您将到处寻找鬼魂。
标签: c++ vector memory-leaks stl