2012-05-05 6 views
31

C++のものを削除することに関して全く混乱しています オブジェクトの配列を宣言し、clear()関数を使用すると、私は完全に混乱します。メモリが解放されたことを確かめることはできますか?例えばC++はベクトル、オブジェクト、フリーメモリを削除します

tempObject obj1; 
tempObject obj2; 
vector<tempObject> tempVector; 

tempVector.pushback(obj1); 
tempVector.pushback(obj2); 

私は安全にすべてのメモリを解放するには、clearを呼び出すことができますか?または、1つずつ削除するために繰り返し処理する必要がありますか?

このシナリオをオブジェクトのポインタに変更した場合、答えは上記と同じになりますか?

+1

ベクトルを指しているという事実以外の第1の場合と第2の場合との違いは何もありません。私はこの質問を広げて、メモリの割り当て/解放がどのように機能すべきか、おそらくポインタについて把握できるようにするべきだと思います。 – Marlon

+0

これは関数スタック内でそれを宣言すると、自動的にデストラクタが終了します。 https://stackoverflow.com/questions/3054567/right-way-to-deallocate-an-stdvector-object –

答えて

62

クリアを呼び出すと、すべてのオブジェクトが破棄されますが、メモリは解放されません。個々の要素をループして(あなたも、オブジェクトを取ることを提案するだろうかアクション?)のいずれかの助けにはなりませんあなたが何ができるか、このです:

割り当てられていないメモリを空のベクトルを作成し、それを交換します
vector<tempObject>().swap(tempVector); 

tempVectorを使用して、メモリを効果的に解放します。

また、C++ 11にはclear()の呼び出し後に呼び出すことができる関数shrink_to_fitがあり、理論的にはサイズに合わせて容量を縮小します(現在は0です)。これはバインドされていない要求ですが、その実装では無視できます。

+0

返信いただきありがとうございます。上記のことを説明してもらえますか?それを呼び出した後、私は明確に電話する必要がありますか? – mister

+3

@dupdupdup:いいえ、あなたは明確に電話する必要はありません。 tempVector内にあったオブジェクトは、空のベクトルに転送されます。次に、空のベクトルは名前のない一時オブジェクトであるため破棄され、以前はtempVectorが所有していた内容が破棄され、メモリの割り当てが解除されます。 –

+0

私はC++のエキスパートではなく、これが 'tempVector.resize(0)'よりも優れている方法を説明しています。 – delnan

14

vector::clear()オブジェクトを格納するためにベクトルによって割り当てられたメモリを解放しません。保持しているオブジェクトのデストラクタを呼び出します。例えば

、ベクターは、バッキングストアとしてアレイを使用し、現在10個の要素が含まれ、その後clear()を呼び出すと、アレイ内の各オブジェクトのデストラクタを呼び出す、が、バッキング配列はそうそこに、を割り当て解除されない場合まだsizeof(T) * 10バイトが(少なくとも)ベクトルに割り当てられています。 size()は0になりますが、size()は必ずしもバッキングストアのサイズではなく、ベクトルの要素数を返します。

2番目の質問では、newで割り当てるものはdeleteで割り当て解除する必要があります。このため、通常はベクトルへのポインタを保持しません。これを実行する正当な理由はめったにありませんし、スコープを離れるときにベクターがクリーンアップされるのを防ぐこともできます。ただし、clear()の呼び出しは、割り当て方法に関係なく同じ方法で動作します。例えば

  1. オブジェクトの有効期間
  2. 記憶域期間

1

{ 
    vector<MyObject> v; 
    // do some stuff, push some objects onto v 
    v.clear(); // 1 
    // maybe do some more stuff 
} // 2 

vあなたはクリア:

18

あり、ここで二つの別々のものがあり、これはすべて破棄します保存していたオブジェクトそれぞれがそのデストラクタを呼び出すと、あなたが書いたものがあれば、MyObjectが所有するものがすべて解放されます。 のベクトルvには、後で必要な場合に備えて、生の記憶域を維持する権利があります。

さらに多くのものを12の間に挿入すると、古いメモリを再利用できるため、時間が節約されます。 2

、ベクトルvはスコープの外に出る:((明示的に再び明らかと呼ばれると思いますかのように)あなたが1ので中に押し込ま任意のオブジェクトが破壊されますが、今基礎となるストレージも解放されvウォン」これ以上使用することはありません)。ポインタはあなたのためにそれをしません2でスコープの外に行くように私は、例を変更した場合


のでvがポインタになり、あなたは、明示的にそれを削除する必要があります。その場合はstd::unique_ptrのようなものを使用する方が良いですが、そうでないとvがリークすると、割り当てられたストレージもリークされます。上記のように、vが削除されていることを確認し、clearを呼び出すだけでは十分ではありません。

+0

「あなたがプッシュすると決めたら、これで古いメモリを再利用できるので時間が節約できます」新しいアイテムを追加するときに古いメモリはなぜ重要ですか? – user13107

+0

ベクトルは、格納するオブジェクトの内部でストレージを管理する必要があります。新しいベクトルを作成するには、新しいストレージを割り当てる必要がありますが、既存のベクターをクリア&再利用すると、すでに割り当てられているストレージの再利用が可能になります。 – Useless

0

ベクトルを繰り返し使用する必要があり、現在のコードでループ内または関数呼び出しごとに繰り返し宣言すると、メモリが不足する可能性があります。私はあなたの機能と使用中のポインタとして渡す、あなたは外でそれを宣言することを示唆している:

my_arr.resize() 

この方法は、あなたのベクトルに対して同じメモリ・シーケンスを使用しての代わりに、新しいシーケンスごとに時間を要求し続けます。 これが役に立ったと思います。 注:異なるサイズにサイズを変更すると、ランダムな値が追加されることがあります。必要に応じて、0などの整数を渡して初期化します。

関連する問題