1. ホーム
  2. c++

[解決済み] std::vector::resize() vs. std::vector::reserve()

2023-04-04 06:13:12

質問

のコメント欄には、以下のようなスレッドがあります。 この記事 の使用について std::vector::reserve()std::vector::resize() .

以下は元のコードです。

void MyClass::my_method()
{
    my_member.reserve(n_dim);
    for(int k = 0 ; k < n_dim ; k++ )
         my_member[k] = k ;
}

に要素を書き込むのは vector に要素を書くには、正しいのは std::vector::resize() ではなく std::vector::reserve() .

実際、以下のテスト コードは VS2010 SP1 のデバッグ ビルドで "クラッシュ"します。

#include <vector>

using namespace std;

int main()
{
    vector<int> v;
    v.reserve(10);
    v[5] = 2;

    return 0;
}

私は正しいのでしょうか、それとも間違っているのでしょうか?また、VS2010 SP1 は正しいのでしょうか、それとも間違っているのでしょうか?

どのように解決するのですか?

理由があって、2種類の方法があります。

std::vector::reserve はメモリを割り当てますが、ベクターのサイズを変更しないので、論理的なサイズは以前と同じになります。

std::vector::resize は実際にベクターのサイズを変更し、デフォルトの状態のオブジェクトでスペースを埋めます。もしそれらがint型であれば、それらはすべて0になります。

リザーブ後、あなたのケースでは、要素5に書き込むために多くのpush_backが必要になります。 それをしたくない場合は、あなたのケースでは、resizeを使用する必要があります。

予約について1つ。push_backで要素を追加した場合、予約した容量に達するまで、ベクター内のデータへの既存の参照、イテレータ、ポインタは有効なまま残ります。つまり、私が 1000 を予約し、サイズが 5 であれば &vec[4] はベクターの要素が1000になるまで同じままです。その後、私は push_back() を呼び出すと動作しますが、格納されたポインタは &vec[4] の保存されたポインタはもはや有効ではないかもしれません。