STL vector の実装について調べてみました。ベクトル コンテナーは動的配列として実装されます。メソッド clear() は、ベクター内のすべての要素を破棄するために使用されます。これにより、ベクターのサイズが 0 に設定されますが、容量は元のままです。したがって、これを正しく理解していれば、すべての要素はデストラクタと呼ばれていますが、動的に割り当てられたメモリは引き続き使用できます。そして、それを解放するために、次のことができます。
Vec.swap( vector<T>() ); // Capacity = 0.
しかし、スワップを使用せず、クリアしただけだとしましょう。内部実装 (私が間違っている場合は訂正してください) は、次のものとほぼ同じです (非常に単純化された方法で):
// A contained type:
struct C {
int m;
C() : m(123){}
};
C * arr = new C[10]; // Suppose this is the internal array in the container
編集: 上記の new 演算子は実際の実装では使用されず、STL はアロケーターを使用することを理解しています。デストラクタをテストするためのテスト ケースとして new を使用しただけです (これは単なるアナロジーです)。
// Calling clear() :
for(size_t i=0;i<SZ;i++)
arr[i].~C(); // Destroying ALL elements
// some other actions . . .
しかし、容量はまだ 10 であり、メモリにはまだアクセス可能なデータがいくつかあります。
// Accessing the vector at 0:
cout<<arr[0].m<<endl; // This prints 123
これは未定義の動作ですか? そうですね、確かに知りたいのですが。
おそらく、デストラクタを呼び出すときに何が起こるか(スタックメモリに関して)をより深く理解していれば、プログラムが関数の範囲外に出たときのデストラクタの呼び出し、またはデストラクタの呼び出しと同じであることがわかります。スコープを出る前は、他のメソッドと同じように見なされ、オブジェクトのスタック メモリは解放されませんか?
免責事項: 上記のコードは、clear() の機能の一部を象徴するために非常に単純化されています。私の調査から得られた結論は、間違っている場合は訂正してください。