10

我在这段代码中有内存损坏:

#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

4

2 回答 2

1

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

int i = 0;

如果 std::string 在其析构函数和 ctors 中有调试输出。你会看到类似:std::string::string 5 次,std::string::~string 5 次,然后

列表大小() = 2

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

例如,就像在这样的表达式中引用 std::string 对象:

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

但是,如果您在示例中将 std::string 替换为“const char *”,我想一切都应该有效。

于 2013-07-08T17:54:30.893 回答
1

初始化器列表的存储在使用后被销毁,即在行之前:

int i = 0;

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

您可以在cppreference 页面找到更多详细信息

于 2013-07-10T07:24:03.177 回答