2

ベクトルのドキュメントから、次のようなクラス メンバ ポインタを持つ値のベクトルの割り当てを完全に解除する適切な方法のように見えます。

std::vector<MyObject>* mvMyObjectVector_ptr;
...
//In the class constructor:
mvMyObjectVector_ptr = new std::vector<MyObject>();

クラスのデストラクタ実装で、以下を順番に呼び出すことです

mvMyObjectVector_ptr->clear();
delete mvMyObjectVector_ptr;

ただし、これにより、SIGABRT の「解放されたポインターが割り当てられませんでした」というエラーが発生するようです。上記のイディオムは、ベクトルへのポインタが指すアドレスに保持されているメモリの割り当てを完全に解除する正しい方法ですか? そうでない場合、正しい方法は何ですか?

4

4 に答える 4

8

はい、正しいです。を使用して割り当てられている場合mvMyObjectVector_ptrnew

さらに、MyObjectで使用するには、特定の要件を満たす必要がありますstd::vector

への呼び出しclear()は冗長であり、省略できます。

考えられる理由には次のようなものがありSIGABRTます。

  • mvMyObjectVector_ptrを使用して割り当てられていませんnew
  • MyObject3 つのルールに違反します。
  • ベクトルを含むクラスは 3 つのルールに違反しています。
于 2013-03-11T19:46:44.857 に答える
5

あなたの問題は、あなたが私たちに示したコードにあるとは思いません。

この行:

//In the class constructor:

クラス内でこれを使用していて、3 のルールを正しく実装していないことを示唆しています。

ベクトルへのポインターを使用しないことをお勧めします。
通常の自動メンバーとして宣言するだけです。

class MyClassContainingVector
{
     public: 
         std::vector<MyObject>          mvMyObjectVector;
                        //   ^^^^^ notice no pointer.
};

これで、正しく自動的に作成および破棄されます。
このオブジェクトを管理するためのコードは、コンストラクタにもデストラクタにも必要ありません。

于 2013-03-11T19:49:41.407 に答える
2

はい、呼び出すことstd::vectorによってオブジェクトを動的に割り当て、new呼び出すことによってその破棄を呼び出すdeleteと、その要素を保持するために内部的に使用されていたメモリが解放されます。

ただし、 RAII のイディオムに従い、自動保存期間を持つオブジェクトを使用する方がはるかに簡単で信頼性が高くなります。

{
    std::vector<MyObject> myVector;
    ...
} // <-- memory is freed here

実行がこのスコープを離れると (例外がスローされるなどによっても発生する可能性があることに注意してください)、myVectorオブジェクトが破棄され、メモリが解放されることが保証されます。

于 2013-03-11T19:50:55.437 に答える
0

ベクトルは通常、動的に割り当てられたポインターとして保持されるべきではありません。ほとんどの場合、これらはクラスの単なるメンバー変数である必要があります(ただし、常に例外があります)。それら「new」によって割り当てられたポインタである場合、単純な「delete」が機能するはずです。

ベクトルはメモリ割り当てを処理するので、そうする必要はありません。ただし、ベクターに保持されているすべてのストレージメモリを本当に解放したい場合は、スタック上にある場合でも、そのための新しい関数があります。

ベクトルだから。reserved()はメモリを拡張するだけで、縮小することはありません。C++ 11では、予約されたメモリを解放する目的で新しい関数vectorが追加されました。シュリンク_to_fit()。実装と彼らがそれでやりたいことを自由に行うことができますが、あなたは基本的に実装にメモリを解放するように求めているので、彼らは合理的な方法で要求に答える必要があります。

次のようにすると、ベクトルを本当にクリアできます。

vector.clear(); //Erases the elements.
vector.shrink_to_fit(); //Erases the memory no longer needed by the elements.

ベクトルがメモリを保持する理由はパフォーマンス上の理由であるため、これを行う必要があるのは、ベクトルにメモリが予約されている理由を実際に理解し、パフォーマンスに対処する意思がある(または対処する必要がないことを知っている)場合のみです。メモリのマイクロ管理から生じるヒット。

于 2013-03-11T19:56:14.323 に答える