Почему первый элемент уничтожен?
У меня есть такой код:
class Data
{
public:
Data(const std::vector<int> &_data)
{
my_data = _data;
}
private:
std::vector<int> my_data;
};
int main()
{
std::vector<std::shared_ptr<Data>> vec = {
std::shared_ptr<Data>(new Data(std::vector<int>({ 1, 2 ,3 }))),
std::shared_ptr<Data>(new Data(std::vector<int>({ 3, 4 ,5 })))
};
// breakpoint
return 0;
}
каким-то образом, когда я приостанавливаю программу для проверки значений (в точке останова), первый (vec[0]
) элемент уничтожается, а второй (vec[1]
) - это нормально. Что здесь происходит? Это ошибка в компиляторе? Я использую новую Visual Studio 2013.
Ответы
Ответ 1
Что происходит, так это то, что ошибка в VS2013 вызывает двойное удаление первого элемента списка initializer_list.
Здесь поток:
-
Создается
- initializer_list.
- целевой вектор зарезервирован размером 1 и первый элемент копируется (через конструктор копирования).
- вектор медленно увеличивается до размера initializer_list.
- initializer_list уничтожается с помощью вектор-деструктора (т.е.
delete[]
). Последний элемент уничтожается первым.
- Первый элемент снова уничтожается через скаляр-деструктор (т.е.
delete
).
Я видел это на другом посту и проверял поведение с помощью отладчика.
См. здесь
Для VS2013, initializer_list подходит только для базовых типов.
Ответ 2
Я думаю, что это что-то с общим указателем, что объект общего указателя будет уничтожен, если
последний оставшийся shared_ptr, владеющий объектом, уничтожается.
последнему оставшемуся shared_ptr, которому принадлежит объект, присваивается другой указатель с помощью оператора = или reset().
Надеюсь, это поможет
Ответ 3
У меня не было VS2013, поэтому я проверяю код в MinGW 4.7 в окнах, я не нашел проблему выше. Когда я останавливаюсь в этой точке останова, первый элемент (vec [0]) и второй (vec [0]) элемент не уничтожаются.
Таким образом, я думаю, что эта проблема состоит в том, что вы пишете какой-то простой код в этой точке останова, а также оптимизируете его, чтобы вы остановились в странном месте точно между двумя деструкторами.
Вы можете опубликовать код дизассемблирования выше, чтобы мы могли явно идентифицировать проблему.:)
Ответ 4
Вероятно, это ошибка в компиляторе. Если вы добавите некоторые записи в конструктор данных и деструктор, вы увидите, что это происходит.
std::cout << __FUNCTION << ":" << this << std::endl;
Я подтверждаю эту проблему в Visual Studio 2013. В разделе "clang" этот код ведет себя как ожидалось.