0

ベクターのメモリ管理がどのように機能するかについて、いくつか質問/例があります。

    vector<int> vec1(10);
    vector<int> vec2(10);        
    vec1 = vec2;

このような場合、vec1 の古いメモリには到達できなくなります。ここでもまだメモリ リークですか、それとも vec2 の古いメモリは、それを参照するものが何もないことに気づき、クリーンアップされますか?

別の例では

struct foo
{
   vector<int> foo_vec(50);
   int* arr; 
}


void myFunction()
{
   vector<foo> vec(10);
   vec[0].arr = new int[50];
   vec.erase(vec.begin());
}

erase()割り当てられたメモリで arr を含む最初のベクター要素で使用したので、erase()そのメモリを解放しますか、それとも消去する前に手動で解放する必要がありますか? またvec、範囲外になった場合、すべてのfoo_vecベクトルがvec自動的にクリーンアップされますか? 助けてくれてありがとう。

4

3 に答える 3

2

の場合

vector<int> vec1(10);
vector<int> vec2(10);        
vec1 = vec2;

intはPODであるため、vec1の以前の内容は消去されます。vectorintsではなくオブジェクトへのポインタで構成されており、これらが割り当てられているnew場合は、割り当てる前にそれらのポインタが指しているものを削除する必要があります。そうしないと、2番目の例に示すメモリリークが発生します。

vector<foo> vec(10);
vec[0].arr = new int[50];
vec.erase(vec.begin());    // this will *not* call delete on vec[0].arr

通常、自分で物事を簡単にするために行うことは、一意のポインター(またはboost :: shared_array / scoped_arrayなど)のようなスマートポインターを使用することです。ベクトルがスコープ外になるか、ベクトルを消去すると、delete(またはdelete [])が自動的に呼び出されます。

struct foo
{
   std::vector<int> foo_vec(50);
   std::unique_ptr<int[]> arr; 
}
...
vec[0].arr.reset(new int[50]);
vec[0].arr[12] = 42;
...
vec.erase(vec.begin());    // this will call delete[] on vec[0].arr
于 2013-03-06T07:15:40.463 に答える
2

erase() はそのメモリを解放しますか、それとも消去する前に手動で解放する必要がありますか?

ルール:常にdeletefor eachを使用しますnew vector魔法ではありません - そのポインターをどのように取得したかがわからないため、削除しません。削除する必要があります。

また、vec が範囲外になった場合、vec 内のすべての foo_vec ベクトルは自動的にクリーンアップされますか?

はい、デストラクタが呼び出され、割り当てが解除されます。ただし、デストラクタがそうでない場合、メモリ リークが発生しますdelete[] arr;


ところで、あなたのコードはカプセル化に違反しています。デストラクタとコンストラクタ (と) でそれぞれ指すメモリを割り当て ( new) と解放 ( ) する必要があります。delete[]foo::arrfoo::foo()foo::~foo()

最後に、必須の質問: なぜa自体foo::arrではないのですか?vector<int>

于 2013-03-06T06:32:50.447 に答える
1
  1. もちろんクリーニング済みです。
  2. いいえ、destructoroffooがこれを行わない場合 (または、消去する前に手動で行わない場合)。
于 2013-03-06T06:30:38.120 に答える