2015-10-16 80 views
3

我想了解更多關於內存如何在C++中處理,並且我有一個關於當變量被重新分配時如何釋放內存的問題。爲了監控內存消耗,我有一個(Linux專用)功能CheckMem(),它調用pmap來查看進程正在使用多少內存。 然後,我只需創建一個大小爲1的矢量,將其重新分配給一個大小爲100萬的矢量,然後再將其重新分配爲大小1,並觀察內存如何變化。C++ 11變量重新分配內存釋放

#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; 
} 

如果我和克編譯++(gcc版本4.8.4),I得到以下輸出:

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

似乎用於大矢量的存儲器(100萬〜雙打8 MB )當載體被重新分配給尺寸1. 但是沒有被釋放,如果我旗-std=c++11,則輸出變化編譯:

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

現在存儲器APPE ars將被重新分配釋放。 C++ 11標準以不同方式處理內存以重新分配?

回答

3

只要庫的實施者大於向量分配的向量的容量,庫的實現者就會重用該向量的容量。這樣他們節省了內存分配。

從C++ 11開始,我們已經移動了賦值,因此當您使用-std=c++11進行編譯而不是重新使用容量時,臨時向量將移動到現有向量中,並且原始向量的內容將移動到臨時對象中。在表達式的結尾處,臨時被破壞,現在你有一個容量較小的向量。

如果你要收縮的矢量的能力,你應該看看:reduce the capacity of an stl vector

+0

是的。這似乎是發生了什麼事情。如果我添加一個'vector (0).swap(vd)',那麼內存在兩種情況下都會被釋放。 – ragnar

+0

引用指出它指出或暗示賦值向量重用賦值向量存儲區的位置是有用的。上次我看,我認爲這是不明確的,但我可能會記住錯誤。 – Yakk

+0

@Yakk我說*更可能*覆蓋,這可能不是問題,但它可能是。我應該澄清一點嗎? – NathanOliver

0

所不同的是這是在C++ 11引入了移動分配。在此之前,如果容量足夠大,您只有複製構造函數會將新矢量複製到舊矢量中。

隨着C++ 11和移動分配新的矢量的數據替換舊的,然後銷燬。