Каков результат, если я использую free с новым или delete с malloc? - PullRequest
4 голосов
/ 29 марта 2010

Это ошибка компилятора или ошибка времени выполнения? Код ниже можно скомпилировать!

class Base{
void g();
void h();
};

int main()
{
    Base* p = new Base();
    free(p);
return 0;
}

Однако он не может быть скомпилирован с виртуальной функцией, если я объявлю класс Base следующим образом

class Base{
virtual void g();
void h();
};

Приведенный ниже код может быть скомпилирован все время, независимо от того, виртуальная функция или нет.

class Base{
void g();
void h();
};

int main()
{
    Base* p = (Base*)malloc(sizeof(Base));
    delete p;
return 0;
}

Ответы [ 3 ]

11 голосов
/ 29 марта 2010

Неопределенный результат, плюс malloc () не вызывает конструкторы, а free () не вызывает деструкторы.

3 голосов
/ 29 марта 2010

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

Если у вас есть «новое» с «свободным», ваши деструкторы не называются. Это обычно приводит к утечке памяти и ресурсов.

Если у вас есть «malloc» с «delete», вы не получаете вызовы конструктора, поэтому ваши объекты неинициализированы. Это может привести ко всем видам ошибок, например, когда деструктор вызывается.

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

Пока что, если все ваши типы - POD (Plain Old Data), вам может повезти, но это очень сильно зависит от вашего компилятора - нет гарантии, что «malloc» и «new» используют одну и ту же кучу, так что вы можете получить повреждение кучи и сбои на некоторых компиляторах.

Короче - не делай этого.

1 голос
/ 29 марта 2010

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

Может произойти все, что угодно , поскольку вы делаете что-то, что стандарт C ++ запрещает делать.

...