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

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

27 голосов
/ 07 августа 2010

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

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;?

Ответы [ 5 ]

37 голосов
/ 07 августа 2010

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

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

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

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

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

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

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

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

7 голосов
/ 07 августа 2010

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

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

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

3 голосов
/ 07 августа 2010

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

Да, это так.

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

Да

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

2 голосов
/ 06 августа 2011

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

2 голосов
/ 07 августа 2010

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

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

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

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

...