2013-07-08 19 views
10

私はこのコードでメモリの破損がありますメモリ破損:: initializer_list

#include <string> 
#include <iostream> 
#include <vector> 
#include <initializer_list> 

int main() { 
    std::vector<std::initializer_list<std::string>> lists = { 
     { 
      {"text1"}, 
      {"text2"}, 
      {"text3"} 
     }, 
     { 
      {"text4"}, 
      {"text5"} 
     } 
    }; 

    int i = 0; 
    std::cout << "lists.size() = " << lists.size() << std::endl; 
    for (auto& list: lists) { 
     std::cout << "lists[" << i << "].size() = " << lists[i].size() << std::endl; 
     int j = 0; 
     for (auto& string: list) { 
      std::cout << "lists[" << i << "][" << j << "] = "<< string << std::endl; 
      j++; 
     } 
     i++; 
    } 
} 

出力例:

lists.size() = 2 
lists[0].size() = 3 
lists[0][0] = text10�j ����text2H�j ����text3`�j ����text4����text5��������q 

問題がstd::initializer_listです。 std::initializer_listからstd::vectorに変更すると問題が解決します。

なぜメモリ破損がstd::initializer_listで発生するのですか?そのためのstd :: stringオブジェクトの

+26

'STDの詳細::理由で自分の名前を持っているinitializer_lists'を見つけることができます。長期保存ではなく初期化*のためだけに使用されるはずです。だから彼らは参照セマンティクスを持っている理由です。すべての 'std :: initializer_list'は実際には' lists'の初期化が終わるまで生きています。 – Xeo

+6

'^^'このコメントは、あなたの質問に対する正解としてシステムによって正式に受け入れられました。私たちのサービスをご利用いただきありがとうございます! –

答えて

1

は、この行の前に破壊されました:のstd :: stringは自分のデストラクタとctorsでデバッグ出力を持つ

int i = 0;

場合。のので のstd ::文字列::列5回、 のstd ::文字列::〜列5回 とその

lists.size後の()= 2

:あなたのようなものが表示されますstd :: stringオブジェクトのコピーが含まれていないinitializre_list、彼ら(一時的なのstd ::文字列objects0作成したとする前に破壊されたが、「;」

それははstdする:: Stringオブジェクト を、このような表現でテイク参照のように、たとえば次のとおりです。

std :: cout < < std :: string( "17");

しかし、あなたの例でstd :: stringを "const char *"に置き換えると、すべて動作するはずです。初期化子リストのストレージが行の前にある使用法、後に破壊され

1

int i = 0; 

その詳細が実装spesificありますが、それは一般的に、構築時に動的配列を作成し、この動的配列は破壊で破壊されます。

あなたはcppreference page