2012-04-19 2 views
0

Я пытаюсь попробовать программу, в которой я выделяю память с помощью «malloc» и выделяю память с помощью «free» ... Я знаю, что использование «нового» и «удалить» это правильный путь, но я просто хочу, чтобы понять ....Нарушение сегментации, в то время как я освобождаю память с помощью «free»

я получаю аварии «нарушение сегментации», но я не мог понять, почему ...

class Object{ 
    public: 
     Object(){ 
      this->def = 10; 
      std::cout<<"Object Constructed"<<std::endl; 
     } 
     ~Object(){ 
      std::cout<<"Object Destructed"<<std::endl; 
     } 
     void amIPresent(){ 
       std::cout<<"Yes Object is Present, Defaulter is "<<this->def<<std::endl; 
      } 
    private: 
     int def; 
}; 


int main(){ 
    std::cout<<"Using malloc to Construct Object"<<std::endl; 
    Object *o = static_cast<Object*>(malloc(sizeof(Object))); 
    Object o2; 
    o = &o2; 
    std::cout<<"Freeing Memory using \"free\""<<std::endl; 
     o->amIPresent(); 
     free(o); 
     return 0; 
} 

Выход:

Using malloc to Construct Object 
Object Constructed 
Freeing Memory using "free" 
Yes Object is Present, Defaulter is 10 
Segmentation fault 
+0

Вы никогда не должны выделять объекты с помощью 'malloc' таким образом! Не вызывать конструктор - это только первая часть проблемы, которую вы будете иметь. Если вы хотите динамически создать новый объект, используйте 'new'. –

+0

Кроме того, в будущем, если вы снова получите что-то вроде сбоя сегментации или других сбоев, сначала следует использовать отладчик, чтобы узнать, что происходит, и изучить переменные. Если вы перешли все заявления и напечатали 'o' на каждом шагу, вы бы поняли проблему довольно четко. –

ответ

4

Becaus e вы переназначаете o, чтобы указать на объект, который не был создан с помощью malloc. Так что называть free нет смысла.

2

Когда вы освобождаете o, он указывает на адрес o2, который был выделен в стеке (как переменная). Вы не должны использовать free для объектов стека.

+0

согласитесь, поэтому delete (stackMemory) в моем случае «02» приводит к нарушению сегрегации. –

0

Я думаю, вы поняли, как работает этот код:

Object *o = static_cast<Object*>(malloc(sizeof(Object))); 
Object o2; 
o = &o2; 

Первый

Object *o = static_cast<Object*>(malloc(sizeof(Object))); 

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

Object o2; 

будет создавать объект в стеке (выделено в стеке и вызывается конструктор). не

o = &o2; 

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

Так что, когда вы используете

free(o); 

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

Вы должны изучить новое место размещения. Смотрите, например What uses are there for "placement new"?

+0

Вот еще один пример использования malloc и размещения new: http://stackoverflow.com/questions/7960556/using-placement-new-malloc-and-free – BertR

0

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

Затем вы освобождаете память, связанную с o2, но затем уничтожается «o2» - так как все переменные на основе стека автоматически появляются, когда вы выходите из их области, - которая пытается освободить уже освобожденную память.

Проблема заключается в том, что вы смешиваете объекты на основе стека и кучи. Никогда не пытайтесь удалить (или бесплатно) объект, созданный в стеке, и, как говорили другие, в C++ придерживаться использования новых и удалять исключительно для объектов с кучей.

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