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

Удаление объекта в С++

Вот пример кода, который у меня есть:

void test()
{
   Object1 *obj = new Object1();
   .
   .
   .
   delete obj;
}

Я запускаю его в Visual Studio, и он выходит из строя в строке с 'delete obj;'. Разве это не нормальный способ освободить память, связанную с объектом? Я понял, что он автоматически вызывает деструктор... это нормально?


Вот фрагмент кода:

    if(node->isleaf())
    {
        vector<string> vec = node->L;
        vec.push_back(node->code);
        sort(vec.begin(), vec.end());

        Mesh* msh = loadLeaves(vec, node->code);

        Simplification smp(msh);

        smp.simplifyErrorBased(errorThreshold);

        int meshFaceCount = msh->faces.size();

        saveLeaves(vec, msh);

        delete msh;
    }

loadleaves() - это функция, которая считывает сетку с диска и создает объект Mesh и возвращает ее. (думаю, что vec и node->code - это просто информация о файле, который нужно открыть)

Должен ли я удалить строку delete msh;?

4b9b3361

Ответ 1

Разве это не нормальный способ освобождения памяти, связанной с объектом?

Это обычный способ управления динамически распределенной памятью, но это не очень хороший способ сделать это. Этот тип кода хрупкий, потому что он не является безопасным для исключений: если при создании объекта возникает исключение, и когда вы его удаляете, вы пропустите этот объект.

Лучше использовать контейнер интеллектуальных указателей, который вы можете использовать для получения управления ресурсами с привязкой к области (обычно это называется сбор ресурсов инициализируется или RAII).

В качестве примера автоматического управления ресурсами:

void test()
{
    std::auto_ptr<Object1> obj1(new Object1);

} // The object is automatically deleted when the scope ends.

В зависимости от вашего варианта использования auto_ptr может не предоставлять семантику, в которой вы нуждаетесь. В этом случае вы можете использовать shared_ptr.

Что касается причины сбоя вашей программы при удалении объекта, вы не предоставили достаточный код для того, чтобы кто-либо мог ответить на этот вопрос с какой-либо определенностью.

Ответ 2

В коде действительно используется обычный способ создания и удаления динамического объекта. Да, это совершенно нормально (и действительно гарантировано языковым стандартом!), Что delete вызовет деструктор объекта, так же как new должен вызвать конструктор.

Если вы не создавали экземпляр Object1 напрямую, а некоторый его подкласс, я бы напомнил вам, что любой класс, который должен быть унаследован, должен иметь виртуальный деструктор (так что правильный деструктор подкласса может быть вызван в случаях, аналогичных этот код), но если ваш примерный код действительно представляет ваш фактический код, это не может быть вашей текущей проблемой - должно быть что-то еще, может быть, в коде деструктора, который вы нам не показываете, или какой-то кучевой коррупции в кода, который вы не показываете внутри этой функции или тех, которые она вызывает...?

Кстати, если вы всегда собираетесь удалить объект непосредственно перед тем, как выйти из функции, которая его запускает, нет смысла делать этот объект динамическим - просто объявите его как локальный (класс хранения auto, как и по умолчанию) указанной функции!

Ответ 3

Разве это не нормальный способ освобождения памяти, связанной с объектом?

Да, это так.

Я понял, что он автоматически вызывает деструктор... это нормально?

Да

Убедитесь, что вы не дважды удалите свой объект.

Ответ 4

если он сбой в строке delete, вы почти наверняка каким-то образом испортили кучу. Нам нужно будет увидеть больше кода для диагностики проблемы, так как представленный вами пример не имеет ошибок.

Возможно, у вас есть переполнение буфера на куче, которая испортила структуры кучи или даже что-то такое же простое, как "double free" (или в случае С++ "двойное удаление" ).

Кроме того, как отметил The Fuzz, у вас может быть и ошибка в вашем деструкторе.

И да, это нормально и ожидается, что для delete вызывается деструктор, который на самом деле является одной из двух его целей (вызовите деструктор, а затем свободную память).

Ответ 5

saveLeaves(vec,msh);
Я принимаю указатель msh и помещает его внутри vec. Поскольку msh - это просто указатель на память, если вы удалите его, он также будет удален внутри вектора.