Повреждение памяти с помощью 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?

Ответ 1

Из-за std::string объекты были уничтожены до этой строки:

int i = 0;

Если std::string имеет отладочный вывод в своих деструкторах и ctors. Вы увидите что-то вроде: std::string:: строка 5 раз, std::string:: ~ строка 5 раз и после этого

lists.size() = 2

Из-за того, что initializre_list не содержит копии объектов std::string, они (временные std::string objects0, только что созданные и уничтоженные до ';'

Это, например, как ссылка на объект std::string в таком выражении:

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

Но если вы замените std::string на "const char *" в вашем примере, все должно работать, я полагаю.

Ответ 2

Хранение для списка инициализаторов уничтожается после использования, которое находится перед строкой:

int i = 0;

Его детали являются реализациями spesific, но обычно они создают динамический массив при построении, и этот динамический массив уничтожается при уничтожении.

Подробную информацию можно найти на странице cppreference