2010-08-07 4 views
24

Вот пример кода, который у меня есть:Удаление объекта в C++

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

я запустить его в Visual Studio, и он выходит из строя в соответствии с «удалить 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;?

+3

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

+0

Вы упомянули ниже функцию loadLeaves, чтобы выделить объект в куче? или он возвращает адрес локального или что-то в этом роде? помните, вы можете только «удалить» то, что вы «новый» ... –

+0

Удостоверьтесь, что деструктор не является приватным! – Vaibhav

ответ

32

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

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

Лучше использовать контейнер интеллектуальных указателей, который вы можете использовать для получения управления ресурсами с ограничением по объему (его обычно называют resource acquisition is initialization или 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, то вы почти наверняка каким-то образом испортили кучу. Нам нужно будет увидеть больше кода для диагностики проблемы, так как представленный вами пример не имеет ошибок.

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

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

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

3

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

Да, это так.

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

Yes

Убедитесь, что вы не double delete ваш объект.

+1

Итак, почему это нормально? Поскольку это переменная-указатель, как это нормально, чтобы автоматически удаляться? Что происходит, сначала я удаляю объект, а затем достигая в строке '}', он снова вызывает деструктор, что вызывает проблему. Мой вопрос: почему он вызывает деструктор автоматически? Если это нормально, то почему люди удаляют объект в этом случае? – Nima

+1

Прочтите эти данные: http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.9 и http://www.parashift.com/c++-faq-lite/freestore-mgmt.html# faq-16.9 'Тогда деструктор Fred :: ~ Fred() будет * автоматом * вызываться при удалении ......' Покажите нам полный код. –

6

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

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

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

1

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

Смежные вопросы