容器中的 C++ STL 内存管理

标签 c++ vector memory-leaks stl

我正在编写一些关键任务代码,我必须确保它绝对没有内存泄漏。我编写了一个小函数,允许我在运行时检索内存使用情况,并在执行某些代码(应该没有泄漏)前后进行测量,以查看内存使用情况是否保持在同一水平。

在调试一段“泄漏”的代码时,我终于发现罪魁祸首是 vector 容器。

重现我所见内容的最少代码如下:

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 标记了一行,如果您分配一个更大的 char 数组,您会看到末尾的“剩余”内存也更大。我不会将此称为泄漏本身,因为显然如果我分配并填充另一个 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

最佳答案

首先,没有理由在您的场景中动态分配您的容器。为什么?

其次,它是char*的容器,虽然它负责管理这些内容,但您对它们指向(或不指向)的任何内容负全部责任!

考虑使用 vector<char> , unique_ptr<char> , string或类似的元素类型,让 vector接受那个任务。

最后,请记住,运行时系统使用自己的基于操作系统原语构建的分配器,因此分配内存不会直接转化为对操作系统的请求,释放/删除它也不会立即将其返回那里。
这样做效率极低

如果您真的想确保将释放的内存返回给操作系统,您基本上有两种选择(都涉及编写您自己的分配器,或者查找并使用其他人构建的分配器):

  • 用您自己的函数替换可替换的全局分配和释放函数。
  • 仅对这些分配使用您自己的分配器(标准容器是分配器感知的,这意味着您可以在每个容器的基础上提供自己的分配器)。

完成后,只需要求分配器将所有内容释放回操作系统即可。

关于容器中的 C++ STL 内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27348373/

相关文章:

c++ - HSI->RGB 转换问题

c++ - map 的键可以是数组吗? (映射数组错误)

c++ - 运行时错误 (SIGABRT) - SPOJ

c++ - QComboBox 子类中的断点不起作用

c++ - 逐行读取文本文件会使 vector 为空

android - 检测绕Y轴的旋转 Android Java

c++ - 如何以 "union-like"的方式更改 C++ vector 的数据类型

c# - 在C#中,事件是否保留对回调方法所在的整个类的引用?

c++ - 在 C++11 中释放动态分配的 uv_timer_t (libuv) 实例

c++ - 使用 C++ 进行面向对象设计中的内存管理