C++ STL vector
3499 ワード
vector
はクラステンプレートであり、テンプレート自体はクラスまたは関数(クラステンプレートおよび関数テンプレート)ではなく、逆にテンプレートをコンパイラがクラスまたは関数を生成する説明と見なすことができる.コンパイラがテンプレートに基づいてクラスまたは関数を作成するプロセスをインスタンス化(instantiation)と呼び、テンプレートを使用する場合、コンパイラがクラスまたは関数をどのようなタイプにインスタンス化するかを指定する必要があります.C++は、ほとんどのタイプのオブジェクトを
vector
の要素として許可することができるが、参照はオブジェクトではないため、参照を含むvector
は存在しない.vector
共通メンバー関数size()
コンテナ内の要素を返すcapacity()
コンテナが現在割り当てられているメモリに格納できる要素を返しますresize(n)
強制容器をn
個の要素を含む状態reserve(n)
強制容器はその容量を少なくともn
に変え、前提はn
現在の大きさvectorオブジェクト成長メカニズム
高速ランダムアクセスをサポートするために、
vector
は要素を連続的に格納し、新しい要素を格納するスペースがなく、新しいメモリ空間を取得しなければならない場合、vector
およびstring
の実装は、通常、新しい空間よりも大きなメモリ空間を割り当て、古い場所から新しい空間に既存の要素を移動し、新しい要素を追加します.古いメモリ内のオブジェクトを解析して、古いメモリ領域を解放します.vector
およびstring
は、いくつかのメンバー関数を提供し、その実装におけるメモリ割り当ての一部とインタラクティブにすることができます.c.shrink_to_fit()
はcapacity()
をsize()
と同じ大きさc.capacity()
メモリを再割り当てせず、c
どれだけの要素を保存できるかc.reserve(n)
少なくともn
要素を収容できるメモリ領域の注意:shrink_to_fit()
はvector
にのみ適用され、string
およびdeque
capacity()
およびreserve
は、vector
およびstring
必要なメモリ容量が現在の容量を超える場合にのみ、
reserve
呼び出しはvector
の容量を変更します.需要が現在の容量より大きい場合、reserve
は少なくとも需要と同じメモリ領域を割り当てます(より大きい場合があります).現在の容量以下であれば、reserve
何もしません.新しい標準ライブラリでは、
shrink_to_fit
を呼び出して、vector
を要求し、string
とdeque
を呼び出して不要なメモリ領域を返却することができます.しかし、特定のインプリメンテーションは、この要求を無視することを選択することができ、すなわち、shrink_to_fit
を呼び出しても、メモリ領域が一定に戻ることは保証されない.vectorメモリ回収
vector
のメモリ占有領域は増加しないため、例えば、まず10000バイトを割り当て、eraseは9999個を削除し、有効な要素を残しますが、メモリ占有量は10000個です.すべてのメモリ容量は、vector
プロファイル時にシステムによって回収されます.empty
コンテナが空であるかどうかを検出するために使用され、clear
はすべての要素を空にすることができる.しかし、clear
であっても、vector
が占有するメモリ容量はそのままであり、メモリの回収は保証されない.空間の動的縮小が必要な場合はdequeの使用を考慮します.vector以外でなければ、swap()を使用してメモリを解放できます.具体的な方法は以下の通りです.
vector nums;
nums.push_back(1);
nums.push_back(2);
vector().swap(nums); // nums.swap(vector ())
あるいは、次のように、大きな括弧のペアを使用します.同じ意味です.
// tmp {}
{
std::vector tmp = nums;
nums.swap(tmp);
}
swap()
は交換関数であり、vector
を自身の役割ドメインから離れ、vector
が占めるメモリ空間を強制的に解放する.要するに、vector
メモリを解放する最も簡単な方法はvector().swap(nums)
である.当時、nums
がクラスのメンバーであり、vector().swap(nums)
をクラスの構造関数に書き込むことができなかった場合、double free or corruption(fasttop)のエラーが発生し、メモリの再解放が原因であった可能性があります.vector
にポインタが格納されている場合、vector
が破棄されると、これらのポインタが指すオブジェクトは破棄されず、メモリは解放されません.次の場合、vector
の要素がnew
操作によって動的に申請されたオブジェクトポインタ:void doSomething()
{
vector vip;
for (int i = 0; i < 5; i++)
vip.push_back(new int);
// do something
for (vector::iterator i = vip.begin(); i != vip.end(); ++i)
delete *i;
}
Reference