2012-02-15 13 views
2

"消去"を含むベクトルの要素を削除すると、消去されたメモリはありません。たとえば、サイズ2000のベクトルを作成します。作成後、プログラムは1,5 MBのメモリを使います。消去呼び出しを行うと、何も消去されません。すべての要素はなくなっています。しかし彼らはまだ記憶に残っています。ベクトルの要素を削除する方法。 (消去は機能しません)

例えば:

#include <iostream> 
#include <vector> 

using namespace std; 


int main() 
{ 
    //Makes a vector of 2000 items 
    vector<int> test(200000); 

    //Pause for test purpose 
    system("pause"); 

    //erase all elements 
    test.erase(test.begin(),test.end()); 

    //Pause for test purpose 
    system("pause"); 

    return false; 
} 

サイズは0を返しますが、プロセスはまだメモリの1,5MBを使用しています。

+2

どのようにプロセスが使用しているメモリを測定しますか? –

+0

たぶん、あなたはこれを読む必要があります。 http://stackoverflow.com/questions/586634/shrinking-a-vector はそれがお役に立てば幸いです。 –

答えて

8

eraseメモリを解放しません。問題のコードtest.capacity() >= 200000が標準で必要です。ベクトルの容量を減らすには、

test.shrink_to_fit(); // in C++11 
vector<int>(test).swap(test); // in C++03 

を使用してください。これは、システムの残りの部分で見られるメモリ使用量が低下することを保証するものではないことに注意してください。プロセスのヒープは一般的にサイズを縮小することはできません。あなたはこのようにそれをテストするようなことがあり

+0

'test'をコンストラクタに渡すのは何ですか?ちょうど空のベクトルと 'temp'を交換するのはなぜですか? – sharptooth

+0

@sharptooth:投稿されたコードはより一般的です。要素のいくつかだけを消去したい場合でも動作します。 – ybungalobill

0

:シンプルな目的のために

int main() 
{ 
    //Makes a vector of 2000 items 
    { 
     vector<int> test(200000); 

     //Pause for test purpose 
     system("pause"); 

     //erase all elements 
     test.erase(test.begin(),test.end()); 

     // Call erase or not, but destructor will be called here - freeing all memory 
    } 

    //Pause for test purpose 
    system("pause"); 

    return false; 
} 

vector.erase deons'tの割り当てを解除メモリ - メモリのおそらく再利用性、それはむしろ、今後の要求のために再配分よりも、割り当てられています。

+0

ベクトルはプロセス全体で使用されます。だから私は私の場合にこれを使うことはできません。 – Laurence

0

プロセスが終了すると、メモリがケースで再利用されます。したがって、ベクトルを消去する必要はありません。
ベクトルをループ内で使用し続ける場合は、clear()を使用してベクトルの内容をクリアすることを検討してください。
ベクターがオブジェクトで使用されている場合、オブジェクトが破棄されるとベクターも破棄されます。
しかし、ベクトルにポインタが含まれている場合は、明示的に削除する必要があります。

+0

生きているときにベクターをきれいにしたい。それはプロセス全体で使用されます。だから私は私の場合にこれを使うことはできません。 – Laurence

+0

他の人が言っているように、swap()やshrink_to_fit()はベクトルを消去します。メモリは再利用されるか、ライブラリやコンパイラの実装に依存しません。 optmizationの理由から、彼らは通常それをしません。 – Jagannath

11

プロセスがメモリを保持する理由2つの理由があります。それが収縮するとき、それは、ない成長するとき

  • std::vector専用メモリを再割り当てしますが。
  • 解放されたメモリは、再利用するプロセスによって保持されることがよくあります。

ベクトルにはshrink_to_fitメンバ関数があり、可能な場合はベクトルの割り当て量を減らすように要求します。しかし、それが実現するという保証はありません。 C++ 03では、またはあなたが余分なメモリが解放されることを保証したい場合は、新たに割り当てられたものとベクトルを交換するのトリックを使用することができます。

std::vector<int>(test).swap(test); 

またはあなたはそれを完全にクリアしたい場合:

std::vector<int>().swap(test); 

このトリックは、割り当てられたメモリの所有権を一時的なベクタに移動します。表現の最後に、そのベクトルが破壊され、メモリが解放されます。

メモリがプロセスから解放されるかどうかは、ライブラリがフリーストアをどのように管理するかによって決まります。多くの場合、小さな割り当て(おそらく数メガバイトまで)はヒープによって処理されます。プロセスはシステムから大きなメモリブロックを要求し、それらを小さな断片に分割します。小片がすべて解放されない限り、ブロックを解放することはできません。多くの実装では、解放されません。

大きな割り当ては、システムから直接要求されることがあります。その場合、解放された時点で解放されます。

だから、あなたは、このようなコードで期待効果を得ることがあります。

// A few gigabytes will probably be allocated directly. 
// You'll have to reduce this on a 32-bit system, or if there's not enough memory 
std::vector<int> test(1000000000) 

// Use the "swap trick" to ensure the memory is deallocated. 
std::vector<int>().swap(test); 

をしかし、たとえこれがプロセスからメモリを解放するという保証はありません。メモリ割り当ての詳細は標準によって規定されておらず、コンパイラ/ライブラリの実装に依存する。

関連する問題