使用std :: initializer_list导致内存损坏

时间:2013-07-08 16:23:54

标签: c++ c++11 memory-corruption

此代码中存在内存损坏:

#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

2 个答案:

答案 0 :(得分:1)

由于std :: string对象在此行之前被销毁:

int i = 0;

如果std :: string在析构函数和ctors中有调试输出。你会看到类似的东西: std :: string :: string 5次, std :: string ::〜字符串5次 之后

lists.size()= 2

由于initializre_list不包含std :: string对象的副本,因此它们(临时std :: string objects0刚刚创建并销毁';'

例如,像参考std :: string对象一样 在这样的表达中:

std :: cout&lt;&lt;的std :: string( “17”);

但是如果你在你的例子中使用“const char *”替换std :: string,那么我认为它应该可行。

答案 1 :(得分:1)

初始化程序列表的存储在使用后销毁,在行之前销毁:

int i = 0;

它的细节是实现特定的,但它通常在构造时创建一个动态数组,这个动态数组在销毁时被销毁。

您可以在cppreference page

找到更多详情