2011-09-28 26 views
1

考慮下面的代碼,與g++ problem.cpp -o problem編譯:問題的內存釋放用於非動態創建的std ::矢量存儲正常(即,非動態分配)數據

#include <vector> 

using namespace std; 

int main() 
{ 
    while(1){} 
    return 0; 
} 

當執行該代碼時,命令top報告〜80K的內存正在被消耗。

現在考慮下面的代碼:

#include <vector> 

using namespace std; 

int main() 
{ 
    vector<int> testVec; 
    for(int i = 0;i<100000000;i++)testVec.push_back(i); 
    while(1){} 
    return 0; 
} 

正如預期的那樣,圍繞〜內存300MB消耗頂部報告。

如今終於,考慮下面的代碼:

#include <vector> 

using namespace std; 

int main() 
{ 
    vector<int> testVec; 
    for(int i = 0;i<100000000;i++)testVec.push_back(i); 
    testVec.clear(); 
    vector<int>().swap(testVec); 
    while(1){} 
    return 0; 
} 

現在top報道說〜4196K被消耗 - 爲什麼不是隻〜80K是在第一個例子(!)?我怎麼能最終釋放可能被矢量所消耗的最後一點內存?除了.clear()之外,我已經讀到了'交換技巧'是爲了釋放所有東西,但顯然它並不像我預期的那樣工作。我錯過了什麼?

+0

向量動態分配他們的數據。他們怎麼會沒有? –

+0

...在底層實現中。我現在看到,也許我的問題陳述確實是天真的,但仍然令人浮想聯翩。 –

+0

由於問題的本質,您正在討論底層實現的最底層細節。你怎麼能同時假裝把它們抽象出來? –

回答

3

你應該忽略它。這個技巧可以將內存從矢量中釋放出來,但這並不意味着分配器(或者甚至是下面的malloc或等效實現)將會使內存回到系統。也就是說,這個向量很可能不是持有記憶的人。

+0

+1:正確。 OP正在試圖制定關於他的進程內存使用行爲的預測,絕對沒有任何公理可以比任何一個相對任意和樸素的代碼與空程序進行比較。 –

+0

嗯......這似乎很奇怪,這種事情可能發生。我的意思是,內存被使用,因爲分配,然後我試圖以唯一可能的方式(?)解除分配。所以我想現在我的問題就變成了:如何確保分配器將內存傳回系統? (我甚至可以控制這個嗎?) –

+0

@本:不,這件事你不應該擔心也不在乎。 –

0

據我所知,有兩種方法來解除分配在這種情況下,內存:

  1. 將使用向量在支架(簡單而有效的)

    { 
        // .......... 
    } 
    
  2. 使用共享代碼指針,但要確保只有一個共享指針。你可以調用「重置」來釋放內存。

    shared_ptr<vector<int> > testVec(new vector<int>); 
    
+0

-1:對不起,但你完全錯過了這一點,這些方法(或多或少)在功能上等同於OP的程序。同時,如果你要強制你不分享它,你爲什麼會使用'shared_ptr'? –

+0

Oic。感謝您的反饋。 – dip

-1

難道你不考慮使用的std :: deque的呢?它具有不同的內存分配策略,並有可能減少分配的內存。 當然,使用大型數據集會導致性能不足。

+0

嗨尤里,是的,我確實考慮過一個deque,但是因爲我只是有興趣添加項目到數組的末尾,因爲我從來沒有做任何插入刪除內部元素,它並不是真的必要。此外,上述David R.指出的問題仍然存在,內存分配/釋放過程部分受其操作系統相關實現的影響。 –

+0

-1:以與dip的答案相同的方式錯過了這一點。 –