2

In C++, it's standard to always use new over malloc(). However, in this question, the most portable way of overloading the new operator while avoiding platform specific code is to place a call to malloc() within it to do the actual allocation.

When overloaded, constructors are called and type-safety is kept. In addition, you can monitor and control how memory is allocated.

My question, when used in this capacity, are there still any downsides to using malloc() within C++?

Community
  • 1
  • 1
Anne Quinn
  • 12,609
  • 8
  • 54
  • 101

3 Answers3

7

If you wish to override new and delete then you pretty much have to use malloc and free. That's how it is meant to be done. Do not be afraid.

The downsides of using malloc() outside of the implementation of new() remain.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Okay, that's what I was wondering. I was worried I might be doing something wrong otherwise, based on what I read about malloc and C++ – Anne Quinn Sep 22 '11 at 04:01
5

The biggest downside I can think off is you can't explicitly call delete or delete [] on a pointer that has been allocated using malloc() without invoking undefined behavior. If you are going to go the highly un-recommended path and use malloc() to allocate memory explicitly for C++ objects, then you are still going to have to call placement new in order to properly call a constructor to initialize the memory location allocated by malloc(). Without an operator new wrapper on malloc(), you'll also have to test to make sure you do not get a NULL return value, and create some code to handle cases where you do without the benefit of throwing an exception. It's also very dangerous, and can incur a number of undefined behaviors, if you simply tried to use C-library functions like memcpy() to copy C++ objects into heap memory allocated with malloc().

Furthermore, because you utilized placement new for your object construction, you are going to have to explicitly call the destructuors for your dynamically allocated objects, and then explicitly call free() on the pointers. This again can cause all sorts of problems if it's not handled correctly, especially if you wanted to work with polymorphic types and virtual base-classes.

If you are going to work with just malloc() and free(), a nice rule of thumb to avoid undefined behavior pitfalls is to keep the objects you allocate and deallocate with malloc() and free() to POD-types. That means non-polymorphic structs or classes with no user-defined constructors, destructors, copy-constructors, assignment operators, private/protected non-static data-members, or base-classes, and all the non-static data-members of the struct/class are POD-types themselves. Since POD-types are basically C-style structs (but with the added ability to define non-static methods and a this pointer), you can safely do C-style memory management with them.

Jason
  • 31,834
  • 7
  • 59
  • 78
  • 1
    I would be overloading `delete` to use free(). I assumed the keyword of delete would call the destructor before passing control over to my overloaded function where I would free the memory. Is that incorrect? – Anne Quinn Sep 22 '11 at 04:05
  • I believe that would only work if the memory allocated and passed to `placement new` came from a call to `malloc()`. Otherwise calling `free()` on a memory location that was not allocated via `malloc()` is undefined behavior. Someone please correct me if I'm wrong ... – Jason Sep 22 '11 at 04:33
  • 1
    This answer seems to have very little to do with use of `malloc` when overloading `operator new`. When overloading `operator new` your job is to allocate a chunk of memory with requested size and return a `void*` to it. `malloc` is fine for that. - The magic of object creation is done automatically if you use the `new` keyword (as opposed to explicitly calling the overloaded `operator new` function. – visitor Sep 22 '11 at 08:59
3

You stated it yourself... the downside to using malloc/free directly in C++ code is that constructors and destructors will not be run; using new/delete ensures that constructors and destructors are run. However, there is nothing wrong with indirectly using malloc via the new/delete operators.

Michael Aaron Safyan
  • 93,612
  • 16
  • 138
  • 200
  • Thanks! I understand the downsides outside the operators, just wanted to make sure the 'never use malloc/free in C++' axiom was one that had an exception here – Anne Quinn Sep 22 '11 at 04:03