Подтвердить что ты не робот

Почему первый элемент уничтожен?

У меня есть такой код:

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.

4b9b3361

Ответ 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" этот код ведет себя как ожидалось.