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

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

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 () - это функция, которая считывает сетку с диска и создает сетку и возвращает его. (Представьте, что vec и node-> code являются просто информацией об открываемом файле)

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

28
задан Unihedron 10 August 2014 в 14:46
поделиться

4 ответа

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

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

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

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

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

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

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

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

37
ответ дан 28 November 2019 в 03:13
поделиться

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

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

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

7
ответ дан 28 November 2019 в 03:13
поделиться

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

Да, это так.

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

Да

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

3
ответ дан 28 November 2019 в 03:13
поделиться

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

Возможно, у вас есть переполнение буфера в куче, которое повредило структуры кучи, или даже что-то более простое, как «двойное освобождение» (или в случае C ++ «двойное удаление»).

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

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

2
ответ дан 28 November 2019 в 03:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: