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