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を要求し、stringdequeを呼び出して不要なメモリ領域を返却することができます.しかし、特定のインプリメンテーションは、この要求を無視することを選択することができ、すなわち、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
  • C++ Primer - Chapter 3.3 & 9.4
  • Effective STL - Item 17