2

使用するのは初めてでSTL、これらのコンテナーで使用されているメモリの割り当てを解除する方法について混乱しています。例えば:

class X {
    private:
        map<int, int> a;
    public:
        X();
        //some functions
}

ここで、コンストラクターを次のように定義するとします。

X::X() {
    for(int i=0; i<10; ++i) {
        map[i]=i;
    }
}

ここで私の質問は、このクラスのデストラクタを作成する必要があるか、またはデフォルトのC++デストラクタがメモリの割り当てを (完全に) 解除するかということです。

上記のクラスへの変更を検討してください

class X {
    private:
        map<int, int*> a;
    public:
        X();
        ~X();
        //some functions
}

ここで、コンストラクターを次のように定義するとします。

X::X() {
    for(int i=0; i<10; ++i) {
        int *k= new int;
        map[i]=k;
    }
}

new によって割り当てられたメモリは、コンテナのデフォルトのデストラクタでは破棄できないため、このようなクラスではデストラクタを記述する必要があることを理解しましたmap(この場合はポインタであるオブジェクトのデストラクタを呼び出すため)。したがって、次のデストラクタを記述しようとします。

X::~X {
    for(int i=0; i<10; ++i) {
        delete(map[i]);
    }
    //to delete the memory occupied by the map.
}

が占有しているメモリを削除する方法がわかりませんmap。関数はありますが、コンテナーのサイズを 0 に減らすと主張していclearますが、必ずしもその下のメモリの割り当てを解除するとは限りません。ベクトルの場合も同じです(STLの他のコンテナだと思いますが、チェックしていません)。

どんな助けでも感謝します。

4

5 に答える 5

4

このクラスのデストラクタを作成する必要がありますか?それとも、デフォルトの C++ デストラクタがメモリの割り当てを (完全に) 解除しますか?

はい、そうなります。すべての標準コンテナーはRAIIの原則に従い、独自の動的リソースを管理します。破棄されると、割り当てられたメモリが自動的に解放されます。

マップが占有しているメモリを削除する方法がわかりません。

あなたはそうしない。で作成した場合にのみ、何かを削除する必要がありますnew。ほとんどのオブジェクトには、メモリの割り当てと解放が自動的に行われます。

マップ自体は、X破棄されるオブジェクトに埋め込まれているため、自動的に破棄され、デストラクタが完了すると、そのメモリはオブジェクトと共に解放されます。

マップによって割り当てられたメモリは、マップの責任です。自動的に呼び出されるデストラクタで割り当てを解除します。

動的に割り当てられたオブジェクトの削除のみを担当しintます。これらを正しく削除するのは難しいため、常に RAII タイプ (スマート ポインターやマップ自体など) を使用してメモリを管理する必要があります。(たとえば、 を使用しnewて例外がスローされた場合、コンストラクターでメモリ リークが発生します。これは、生のポインターではなく、オブジェクトまたはスマート ポインターを格納することで簡単に修正できます。)

于 2013-05-28T17:49:40.807 に答える
2

STL コレクションが破棄されると、含まれているオブジェクトの対応するデストラクタが呼び出されます。

これは、

class YourObject {
  YourObject() { }
  ~YourObject() { }
}

map<int, YourObject> data;

次に、のデストラクタYourObjectが呼び出されます。

一方、次のようにオブジェクトへのポインタを格納している場合

map<int, YourObject*> data

次に、ポインターの destruct が呼び出され、ポインター自体は解放されますが、指定されたコンストラクターは呼び出されません。

解決策は、 のようなオブジェクトを保持できるものを使用することです。これは、保持shared_ptrされた項目オブジェクトへの参照がなくなったときにそのオブジェクトを呼び出すことを気にする特別なオブジェクトです。

例:

map<int, shared_ptr<YourObject>>
于 2013-05-28T17:47:55.587 に答える
1

扱っているコンテナのタイプを無視してコンテナと考えれば、コンテナに入れるものはすべて、コンテナの所有者によって所有されていることに気付くでしょう。これは、そのメモリを削除するのは所有者次第であることも意味します。あなたのアプローチは、割り当てたメモリの割り当てを解除するのに十分です。マップ オブジェクト自体がスタック割り当てオブジェクトであるため、そのデストラクタが自動的に呼び出されます。

または、このタイプの状況のベスト プラクティスは、生のポインターではなく、shared_ptr または unique_ptr を使用することです。これらのラッパー クラスは、メモリの割り当てを自動的に解除します。

map<int shared_ptr<int>> a;

http://en.cppreference.com/w/cpp/memoryを参照してください

于 2013-05-28T17:47:39.957 に答える
0

簡単に言えば、コンテナー自体が破棄されると、コンテナーは通常、その内容の削除を処理します。

これは、コンテナー内のオブジェクトを破棄することによって行われます。そのため、どうしてもやりたい場合は、(ctor などで) メモリを割り当てることによってメモリを誤って管理するタイプを作成できますが、適切に解放されません。ただし、これらのオブジェクトの設計を修正することで明らかに修正する必要があります (たとえば、オブジェクトが所有するメモリを解放する dtor を追加するなど)。または、生のポインターを格納するだけで同じ効果を得ることができます。

同様に、正しく動作しない Allocator を作成することもできます。つまり、メモリを割り当てても、メモリの解放を求められても何もしませんでした。

これらのケースのすべてにおいて、本当の答えは「それをしないでください」です。

于 2013-05-28T17:49:10.973 に答える