views:

120

answers:

3

It is a compiler error or runtime error? The code below can be compiled!

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

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

However it can't be compiled with a virtual function if I declare the class Base like this

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

The code below can be compiled all the time, no matter the function is virtual or not.

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

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

Undefined outcome, plus malloc() doesn't call constructors and free() doesn't call destructors.

Nick D
Since behaviour is undefined, `free()` *could* call destructors if you pass it a pointer allocated with `new`. I agree that "it doesn't" in the sense that I doubt there are any implementations in which it does.
Steve Jessop
Yes, but you also face the problem that memory allocated by new, isn't guaranteed to be compatible with free. Ditto malloc and delete.
Joe D
+3  A: 

As the comment says - the result is that the behaviour of the program is undefined.

If you have "new" with "free", your destructors aren't called. That typically leads to memory and resource leaks.

If you have "malloc" with "delete", you don't get constructor calls so your objects are uninitialised. That can lead to all kinds of errors, e.g. when the destructor is called.

As indicated by the comment below, there's things in Non-POD types (such as classes that have virtual methods and classes that use virtual inheritance) that need initialisation even if it's not immediately obvious that constructor initialisation is needed. If you malloc an object then call a virtual method, the most likely outcome is that your program will crash.

So far, if all your types are POD (Plain Old Data) you may get lucky, but that depends very much on your compiler - there's no guarantee that "malloc" and "new" use the same heap, so you could get heap corruption and crashes on some compilers.

In short - don't do it.

Steve314
You're right but in practice, I've never encountered a compiler that doesn't use malloc/free to allocate the memory for global new/malloc - though of course this can't be relied on
zebrabox
POD types cannot have virtual functions, so the second one is not a POD type.
James McNellis
@James - I'm describing general principles. As you say, virtual functions are clear evidence that the type isn't POD, and the obvious problem with malloc for this is that the virtual pointer isn't initialised so calls to late-binding methods will crash.
Steve314
A: 

It's undefined behavior. That means anything could happen -- the program could succeed, it could crash hard, it could silently fail and crash much later in an unrelated innocent-looking piece of code, or it could even erase your hard drive.

Anything could happen, since you're doing something the C++ standard says not to do.

Adam Rosenfield