63

このコードを考えてみましょう:

#include <vector>

void Example()
{
    std::vector<TCHAR*> list;
    TCHAR* pLine = new TCHAR[20];
    list.push_back(pLine);
    list.clear();    // is delete called here?
    // is delete pLine; necessary?
}

各要素をlist.clear()呼び出しますか?deleteつまり、前後にメモリを解放する必要がありlist.clear()ますか?

4

6 に答える 6

53

std::vectorが呼び出されたときに、含まれているすべての要素のデストラクタを呼び出しますclear()。あなたの特定のケースでは、それはポインタを破壊しますが、オブジェクトは残ります。

スマートポインタは正しい方法ですが、注意してください。auto_ptrstdコンテナでは使用できません。boost::scoped_ptrどちらもできません。boost::shared_ptrできますが、オブジェクトへのポインタがないため、実際には配列を使用しているため、この場合は機能しません。したがって、問題の解決策はを使用することboost::shared_arrayです。

std::basic_string<TCHAR>ただし、代わりに、文字列を操作するメリットを享受しながら、メモリ管理を行う必要がない場合に使用することをお勧めします。

于 2009-02-27T09:35:39.927 に答える
40

いいえ(ハゲポインターの破壊は何もしないので、例で提案するように、最後に自分で削除を行う必要があります)。ただし、ブースト[または他のRAIIベースのイディオム]スマートポインターを使用して、auto_ptr正しいことを実行することはできます(コピーなどで互換性のない動作をするため、コンテナーでは正しく機能しません)。使用する前にそのようなスマートポインタ。(Benoitが言及しているように、この場合、basic_stringあなたが本当にここで探しているものです。)

スマートポインタの落とし穴を理解する必要があると言っても、メモリ管理を暗黙的に処理して、明示的に行う必要がないようにすることで、エラーが発生しにくくなります。

編集:EarwickerとJames Mattaからの強力な提案のおかげで、Benoitが彼のはるかに徹底的な答えにもたらした要素を含むように大幅に改訂されました-これについてデューデリジェンスを行うように私を促してくれてありがとう!

于 2009-02-27T09:28:29.897 に答える
9

そうでないことを確認できる 1 つの方法を次に示します。完全に定義されていないクラスで試してみてください。

#include <vector>
class NotDefined;

void clearVector( std::vector<NotDefined*>& clearme )
{
    clearme.clear();    // is delete called here?
}

このスニペットがコンパイルされる場合、デストラクタが定義されていないため、デストラクタを呼び出すことはできません。

于 2009-02-27T13:32:18.720 に答える
8

これを行う単純なテンプレート関数を書くことができます:

template <class T>
void deleteInVector(vector<T*>* deleteme) {
    while(!deleteme->empty()) {
        delete deleteme->back();
        deleteme->pop_back();
    }

    delete deleteme;
}

ここの何かが悪い習慣かもしれませんが、そうは思いません。コメントはいつもいいですが、私には大丈夫に見えます。

于 2009-11-16T04:47:33.760 に答える
6

いいえ。他の場所でポインタを使用していないという保証はないため、これは行われません。ポインタ変数でない場合は、(デストラクタを呼び出すことによって)それらを解放します。

于 2009-02-27T09:29:13.953 に答える