2

通常、非ローカル スコープにある STL オブジェクトを使用するときは、保存したいデータへのポインターを保存します。例えば

std::vector<MyStruct*> 

ベクターをクリーンアップするときが来たら、すべてを削除します。私は最近、思っていたようにこれが必要ではないことに気づきました。なんらかの理由で、STL クラスはデータをスタックに格納すると考えていましたが、今ではヒープに割り当てると考えています。これは正しいです?コピー時間を短縮するためにオブジェクトをポインタとして保存することの唯一の本当の利点は?

4

4 に答える 4

8

標準コンテナーは、型がテンプレート パラメーターとして渡される Allocator オブジェクトを介してメモリを割り当てます。他に何も渡さない場合、それは になり、メモリの割り当てにstd::allocator<T>使用されます。new

結論: ほとんどどのような方法でもメモリを割り当てるように強制できますが、デフォルトでは、空きストアから割り当てられます。

ポインターのコンテナーが本当に必要で、コンテナーがポインティング先オブジェクトを所有する場合 (たとえば、オブジェクトが破棄されるとそれらを自動的に削除する場合)、Boost Pointer Containersを参照することをお勧めします。

于 2012-07-28T09:56:55.660 に答える
3

ポインタを使用してコピー時間を短縮すること、真のメリットです。それによって改善できるすべてのベクトル操作を考えてみてください。たとえば、並べ替えなどです。

もう 1 つの本当の利点 (上記のコメントで述べたように) は、ポリモーフィズムを使用して、関連するオブジェクトを同じベクトルに格納できることです。スカラー オブジェクト (非ポインター) では実行できないこと。

データをスタックに保存するかヒープに保存するかは、そのオブジェクトの移動にかかるコストに違いはありません (まあ...そうですが、たいていは無視できる程度で、この議論には関係ありません)。

オブジェクトへのポインタを STL ベクトルに格納すると、ベクトルはオブジェクトの所有権を取得しません。十分な注意を払い、必要がなくなったらクリーンアップする必要があります。

于 2012-07-28T09:54:40.890 に答える
3

[...]一方、ヒープに割り当てると思います。これは正しいです?

はい。ベクトルを次のように宣言した場合:

std::vector<MyStruct*> v;

次に、基本的にポインターをベクターに格納しているため、ベクターは、ポインターが指すオブジェクトではなく、ポインターを格納するためにメモリを割り当てます。したがって、デストラクタが実行されると、ベクトルは割り当てたメモリの割り当てを解除しますが、ポインタ自体のメモリの割り当てを解除しません。つまり、ベクトルに格納されたポインタが指すメモリの割り当てを解除しません。

ただし、これを宣言すると、次のようになります。

std::vector<MyStruct> v;

次に、オブジェクト自体を保存しているため、ベクターはオブジェクトを保存するためにメモリを割り当て、デストラクタの実行時にメモリの割り当てを解除します。

于 2012-07-28T09:56:13.690 に答える
2

ベクターをクリーンアップするときが来たら、すべてを削除します。私は最近、思っていたようにこれが必要ではないことに気づきました。

それを仮定しないでください。ベクトル内のポインターが動的に割り当てられたメモリを指している場合、ベクトルはそれを行わないため、そのメモリを削除する必要があります

たとえば、コードがタイプの場合

 MyStruct* pNewStruct = new MyStruct;
 myVector.push_back(pNewStruct);

 ...
 ...

 myVector.clear();

ベクトルに追加する各要素に割り当てたメモリを具体的に削除していないため、メモリリークが発生しています。ベクターは、動的配列の一部として割り当てられたメモリを解放しますが、これはポインタの配列を解放するだけで、ポインタが指すメモリは解放しません。

于 2012-07-28T09:52:27.137 に答える