2016-11-21 13 views
0

ビジュアルスタジオ2013では、std :: vectorを作成し、いくつかの文字列を格納しています。それからベクトルの文字列をコピーして最後に追加したいのですが(挿入を消去した後にそれらを移動すると仮定します)、insertメソッドを使用して、最後に空の文字列しか見ませんでした。奇妙な。私は "0" "1" "2" "3" "4" "5" "6" "" "" ""std :: vector <std::string>空の文字列を代わりに挿入

がある何を得る

std::vector<std::string> v; 
std::string s = "0"; 
for (int i = 0; i < 7; ++i) 
{ 
    s[0] = '0' + i; 
    v.push_back(s); 
} 
v.insert(v.end(), v.begin(), v.begin() + 3); 
for (std::string& s : v) 
    std::cout << "\"" << s.c_str() << "\" "; 

、いくつかの簡単なテストコードでそれを再現しました

私はベクトルクラスの_Insert(..)メソッドの内部で、挿入メソッドにデバッグしました。メモリの再割り当て、メモリの移動/移動などを行いました。

最初の_Umove呼び出しは、7つの文字列を新しい割り当てメモリに移動します。std :: moveが呼び出され、古いメモリに空の文字列が残っていると思います。

次に、_Ucopyメソッドは3つのアイテムをコピーしようとしますが、古いメモリからは空の文字列が3つ追加されます。 別の_Umove呼び出しがありますが、わたしはそれが何であるか分かりません。すべての後、古いメモリが解放され、新しいメモリがベクターに接続されます。

intのようなスカラー型を使用しても、メモリがコピーされるため間違った出力が行われることはなく、std :: moveは呼び出されません。

ここで何か間違っているのですか、それともMS Visual StudioのSTLバグですか? this std::vector::insert referenceから

答えて

1

:新しいsize()が古いcapacity()より大きい場合

は、再配分を引き起こします。新しいsize()capacity()よりも大きい場合は、すべてのイテレータと参照が

を無効にしている[重点鉱山]

イテレータを使用してベクトルを反復しながら、あなたは、ベクターに要素を追加しています。これにより、ベクトルが再割り当てされる可能性があるため、イテレータは無効になります。これにより、の未定義の動作が発生します。

+0

私が理解しているように、再配置はイテレータと参照が無効になる原因になります。ベクターへの反復子と参照は無効になりますが、これは呼び出し中に発生します。それは私にとっては不思議です。私は挿入する前にいくつかの領域を予約しようとすると、それは動作します。唯一の回避策です。私は後で他のコンパイラで試してみる。 –

+0

@TigerHwang 2つのイテレーターを 'insert'関数に渡しています。 'insert'関数が新しい要素のためのスペースを作るとすぐに、あなたが渡すイテレータは無効になります。別のコンパイラを使用しても問題は解決しません。スペースの確保は唯一の解決策です。 –

+0

私の目的は、ベクトル内のいくつかの文字列を最後まで移動することです。したがって、別のメソッドstd :: move(v.begin()、v.begin()+ 3、v.end())を試しました。これは、イテレータ+オフセットが範囲外であるためにアサーションの失敗を引き起こします。 std :: move(v.begin()、v.begin()+ 3、v.end() - 3)は失敗しませんが、結果は私が望むものではありません。なにか提案を? –

関連する問題