可变重新分配中的C ++ 11内存释放

时间:2015-10-16 18:21:37

标签: c++ linux c++11 memory vector

我想了解更多关于如何在C ++中处理内存的问题,并且我有一个关于在重新分配变量时如何释放内存的问题。为了监视内存消耗,我有一个(特定于Linux的)函数CheckMem(),它调用pmap来查看进程使用了​​多少内存。 然后,我只需创建一个大小为1的向量,将其重新分配给大小为一百万的向量,然后再将其重新分配给大小为1,并观察内存如何变化。

#include <iostream>
#include <vector>
#include <sstream>
#include <cstdio>
#include <unistd.h>

using namespace std;

void CheckMem()
{
  char cmdstring[100],outbuf[500],buf[100];
  sprintf(cmdstring,"pmap -x %d | tail -1",getpid()); 
  FILE* output = popen(cmdstring,"r");
  fgets(outbuf,500,output);
  size_t kb,rss,dirty;
  istringstream ss(outbuf);
  ss >> cmdstring >> buf >> kb >> rss >> dirty;
  cout << "RSS: " << rss << " KB" << endl;
}

int main()
{
 vector<double> vd(1);
 CheckMem();
 vd = vector<double>(1000000);
 CheckMem();
 vd = vector<double>(1);
 CheckMem();
 return 0;
}

如果我用g ++(gcc版本4.8.4)编译,我得到以下输出:

RSS: 1184 KB
RSS: 9128 KB
RSS: 9136 KB

当向量重新分配为1时,似乎不会释放用于大向量(1百万双倍~8 MB)的内存。 但是,如果我使用标志-std=c++11进行编译,则输出会更改:

RSS: 1180 KB
RSS: 9112 KB
RSS: 1300 KB

现在内存似乎被重新分配释放。 C ++ 11标准是否以某种方式以不同方式处理内存以进行重新分配?

2 个答案:

答案 0 :(得分:3)

图书馆的实施者很可能会重复使用矢量的容量,只要它大于您指定给它的矢量的容量。这样他们就可以节省内存分配。

从C ++ 11开始,我们移动赋值,因此当您使用-std=c++11进行编译而不是重用容量时,临时向量将移动到现有向量中,并且原始向量的内容将移动到临时向量中。在表达式结束时,临时表被破坏,你现在有一个容量较小的向量。

如果你想缩小矢量的容量,你应该看看:reduce the capacity of an stl vector

答案 1 :(得分:0)

不同之处在于C ++ 11中引入的移动分配。在此之前,你只有复制构造函数,如果容量足够大,它会将新的向量复制到旧向量中。

使用C ++ 11并且移动分配新的向量的数据将替换旧的向量,然后将其销毁。