2013-07-08 32 views
10

我在這個代碼內存損壞:內存與腐敗的std :: 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發生?

+26

'STD詳細:: initializer_lists'有他們的名字是有原因的。它們應該只用於*初始化*,而不是長期存儲。這就是爲什麼他們有引用語義。你所有的'std :: initializer_list'實際上只有在'lists'初始化結束之前才存在。 – Xeo

+6

'^^'該評論已被系統正式接受爲您的問題的正確答案。感謝您使用我們的服務! –

回答

1

因爲的std :: string對象的這條線之前被摧毀:

int i = 0;

如果的std :: string具有調試輸出在他們的析構函數和構建函數。你會看到類似這樣的: 的std :: string :: string的5倍, 的std :: string ::〜串5倍 和

lists.size後()= 2

由於initializre_list不包含的std :: string對象的拷貝,它們(剛剛創建之前銷燬臨時的std :: string objects0「;」

它是例如像取參考的std :: string對象 在這樣的表達:

std :: cout < < std :: string(「17」);

但是,如果你在你的例子中用「const char *」替換std :: string,那麼所有的都應該可以工作,我想。

1

存儲用於初始化列表是使用後銷燬,這是前行:

int i = 0; 

對它的詳細實施spesific,但它通常產生在施工動態數組並將該動態數組在破壞被破壞。

你可以找到cppreference page