11

私の知る限り、両方のベクトル宣言について次のようになります。

//TYPE 1
std::vector<cls> vec;     //cls is user defined datatype(A class)

ベクトルのメモリはスタックに割り当てられ、ベクトルの内容のメモリはヒープに割り当てられます。

以下の宣言にも当てはまります(間違っている場合は訂正してください):

//TYPE 2
std::vector<cls*> vec;    //cls is user defined datatype(A class)

タイプ 1 のベクトルが範囲外になると、そこに格納されているオブジェクトのメモリの割り当てが解除されます。

しかし、次のように要素を挿入すると (適切なオーバーロードされたコンストラクターがあると仮定して)、タイプ 2 で何が起こるか、ベクトルが範囲外になります。

vec.push_back(new cls(5));

clear を明示的に呼び出してみましたが、デストラクタは呼び出されませんでした。メモリの割り当てが自動的に解除され、デストラクタが呼び出されますか。そうでない場合は、それを達成する方法。

また、ベクトルを次のように宣言した場合、ベクトルとコンテンツに割り当てられたメモリはどこにありますか。

std::vector<cls*> *vec = new std::vector<cls*>;
4

8 に答える 8

4

しかし、次のように要素を挿入すると (適切なオーバーロードされたコンストラクターがあると仮定して)、タイプ 2 で何が起こるか、ベクトルが範囲外になります。

deleteメモリがリークします - ベクトルと各要素を個別に反復処理する必要があります。

于 2013-07-29T13:46:50.173 に答える
2

vector のメモリは必ずしもスタックに割り当てられるとは限りません。最後のスニペットで示したように、ベクターのメモリはヒープから割り当てることができます。

ベクターがスタックからスコープ外に出た場合、またはベクターが new でヒープに割り当てられている場合に削除で破棄された場合、そのすべての要素が自動的に破棄されます。ただし、通常のポインターにはデストラクタがなく、死ぬときに指しているオブジェクトに対して特別なことは何もしません。したがって、ポインターのベクトルをクリアするとポインターが破棄されますが、ポインターが指すオブジェクトは破棄されません。

解決策は 2 つあります。ベクターをクリアする前に、ベクター内のすべてのポインターを反復処理し、delete を呼び出します。より良い解決策は、unique_ptr などのスマート ポインターを使用することです。unique_ptr が破棄されると、それが指すオブジェクトは自動的に削除されます。

だから

vector<unique_ptr<cls>>

、あなたが行ったように新しいclをプッシュバックできます。ベクトルが破棄されると、unique_ptrを介してベクトルに挿入したすべてのclsオブジェクトも破棄されます。

于 2013-07-29T13:47:54.073 に答える
2

ポインタを保持するベクトルは、ポインタが指すメモリを担当しません。ベクトルがスコープ外になると、これらのポインターが指すメモリーではなく、ポインター用に持っていたメモリーが解放されます。

この記憶を管理するのはあなたの責任です。そのため、スマート ポインターを として使用するかstd::unique_ptrstd::shared_ptrメモリ リークを回避する必要があります (手動で削除するのを忘れた場合に発生する可能性があります)。

また、ベクトルを次のように宣言した場合、ベクトルとコンテンツに割り当てられたメモリはどこにありますか。

vector<cls*> *vec = new vector<cls*>;

ベクトルはヒープ上にあり、コンテンツはどこにでもあります (たとえば、 で割り当てた場合はヒープ上にあり、 :をnew実行した場合はスタック上にある可能性があります) 。cls myCls; cls* myPointerToCls = &cls;vec.push_back(myPointerToCls);

于 2013-07-29T13:48:35.190 に答える