我编写了一些关键任务代码,我必须确保它完全没有内存泄漏。我写了一个小函数,允许我在运行时检索内存使用情况,并在执行某些代码之前和之后进行测量(应该是无泄漏的),以查看内存使用情况是否保持在同一级别。
在调试一段泄漏的代码时,我终于发现罪魁祸首是一个矢量容器。
重现我所看到的内容的最小代码如下:
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();
),您会看到你的程序应该使用大约20M左右的内存。
我想了解为什么会这样。我用A
标记了一行,如果你分配了一个更大的字符数组,你会发现剩下的字符串是&#39;最后的记忆也更大。如果我分配并填充另一个STL容器,我本不会将此称为泄漏,显然可以重用内存,但我仍然期望在代码完成时完全释放该内存。
有人可以了解为什么这个记忆仍在使用?我怎么可以免费&#39;这是真的吗?
有关我的编译器环境的一些细节:
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
答案 0 :(得分:3)
首先,没有理由在您的方案中动态分配容器。为什么呢?
其次,它是char*
的容器,虽然它负责管理这些容器,但您对其指向(或不指向)的任何内容保留全部和唯一的责任!
考虑使用vector<char>
,unique_ptr<char>
,string
或类似的东西作为元素类型让vector
接受该任务。
最后,请记住,运行时系统使用自己的基于OS原语构建的分配器,因此分配内存不会直接转换为对OS的请求,也不会立即释放/删除它。
这样做会非常低效。
如果确实想要确保将释放的内存返回给操作系统,那么基本上有两个选项(它们都涉及编写自己的分配器,或者找到并使用其他人构建的): / p>
完成后,请让分配器将所有内容发布回操作系统。