5

What is the use of malloc and free when we have new and delete in C++. I guess function of both free and delete is same.

Parag
  • 7,746
  • 9
  • 24
  • 29

3 Answers3

8

They're not the same. new calls the constructor, malloc just allocates the memory.

Also, it's undefined behavior mixing the two (i.e. using new with free and malloc with delete).

In C++, you're supposed to use new and delete, malloc and free are there for compatibility reasons with C.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Okk. but both of them are used for memory management. so when to use new and when to use malloc? – Parag Apr 02 '12 at 07:16
  • 4
    @Parag Doesn't "In C++, you're supposed to use new and delete" answer that? Don't use malloc/free. –  Apr 02 '12 at 07:17
  • @hvd: That is not the correct advice.Your rationale of just using `new` and `delete` in C++ is not entirely correct(Especially after Nicol's reply to your comment.) – Alok Save Apr 02 '12 at 07:35
  • 1
    @Als Nicol's reply is a possible reason not to use `new char[]`, but no reason not to use `::operator new`, which I had mentioned in the comment he replied to. There's still no need to use `malloc`. –  Apr 02 '12 at 11:33
5

In C++, it is rarely useful that one would use malloc & free instead of new& delete.

One Scenario I can think of is:

If you do not want to get your memory initialized by implicit constructor calls, and just need an assured memory allocation for placement new then it is perfectly fine to use malloc and free instead of new and delete.

On the other hand, it is important to know that mallocand new are not same!
Two important differences straight up are:

  • new guarantees callng of constructors of your class for initializing the class members while mallocdoes not, One would have to do an additional memset or related function calls post an malloc to initialize the allocated memory to do something meaningful.

  • A big advantage is that for new you do not need to check for NULL after every allocation, just enclosing exception handlers will do the job saving you redundant error checking unlike malloc.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • Sure, but an explicit call to `operator new` suffices for that, or `new char[n]`. (Nothing wrong with using malloc for that, but it's not necessary.) –  Apr 02 '12 at 07:18
  • 2
    @hvd: `new char[]` has some (very small) overhead. Namely, it stores the number of characters allocated in the memory block. – Nicol Bolas Apr 02 '12 at 07:20
  • @NicolBolas: And how does `free` know how much to free? `malloc` will store the number of bytes allocated too. – MSalters Apr 02 '12 at 07:51
  • @MSalters or some means of finding the following block in memory. Something like `new MyClass[]` must generally store the exact count as well, in order to call the correct number of destructors, since this information cannot be derived otherwise. `new char[]` may also do this (for reasons of orthogonality---it won't need the count); the ones I know don't. – James Kanze Apr 02 '12 at 07:59
  • 3
    @Als One important difference between `malloc()` and `::operator new()`. You can legally replace `::operator new()`, and `malloc()` is guaranteed not to use `::operator new()` in its implementation, so you can use `malloc()` in an override of `operator new()`. (Formally, `malloc` and `free` are the only functions which have this guarantee. In my implementations of `::operator new()`, It tend to assume that functions like `memset` and `memcpy` don't invoke `::operator new()` either.) – James Kanze Apr 02 '12 at 08:01
  • @JamesKanze: True, if you need exact N dtors called, then you'd better store N. But I was confirming was hvd said: `new char[N]` is a perfectly sane way to allocate raw memory and, as you confirmed, on many implementations there is no difference in overhead. – MSalters Apr 02 '12 at 08:04
  • @MSalters Yes. The standard actually guarantees that `new char[N]` be correctly aligned for all possible types (so the alignment requirements for the return value of `new char[N]` are greater than those for `new int[N]`). From a readability point of view, however, I'd prefer to see `::operator new(N)` used when the goal is to acquire raw memory. – James Kanze Apr 02 '12 at 08:29
  • @JamesKanze: Does the guarantee that `malloc()` will never call `::operator new()` arise from the fact that `malloc()` was incorporated in to C++ only for backard compatibility with C, & Is this an implicit guarantee or has the Standards committee specifically & conciously marked `malloc()` for this purpose by stating this explicitly? My question is more about the rationale rather than the exact standard quotes. – Alok Save Apr 02 '12 at 08:43
  • @Als No. There is (or was at one time) an explicit guarantee that `malloc` will not call `::operator new`. There was, back in the early days, a certain euphoria about C++, and a belief in certain communities that it would replace C everywhere, and that implementations of C would only exist for reasons of backwards compatibility, and that there would be implementations in which the C library would be written in C++. So, for example, `printf` would e implemented using `<<` on an `ostream`. (As far as I know, it's never happened.) – James Kanze Apr 02 '12 at 08:53
3

First, when you speak of new and delete, I assume you mean the expressions, and not the operator new and operator delete functions. The new and delete expressions are not related to malloc and free, and only manage memory incidentally; their main role is to manage object lifetime: a new expression will call the operator new function to obtain memory, and then call the constructor; a delete expression will call the destructor before calling operator delete to free the memory. For the most part, objects should be created, and not simply allocated, which means using the expressions exclusively.

There are some rare cases where one wants to separate allocation and initialization (creation); implementing things like std::vector is a classical example, where you'll allocate for many objects in one go, but only construct one at a time. In such cases, you'll use the operator new function for allocation, and placement new for initialization; at the other end, you'll explicitly call the constructor (something like p->~T()) for destruction, and use the operator delete function to free the memory.

Off hand, I can only think of two cases where you'd use malloc and free in C++. The first is to implement your own replacements of the ::operator new and ::operator delete functions. (I often replace the global ::operator new and ::operator delete with debugging versions, which trace allocations, put guard zones around the allocated memory, etc.) The other is when interacting with a legacy library written in C: if the library says to pass a pointer to memory allocated by malloc (because it will free it itself using free), or more commonly, returns a pointer to memory allocated by malloc, which you're expected to free, then you must use malloc and free. (The better libraries will provide their own allocation and deallocation functions, which do more or less what the new and delete operators do, but there will always be things like strdup().)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • For those interested in the first use stated in the answer, [How should I write ISO C++ Standard conformant custom new and delete operators?](http://stackoverflow.com/questions/7194127/how-should-i-write-iso-c-standard-conformant-custom-new-and-delete-operators) is an good read. – Alok Save Apr 02 '12 at 08:52
  • @Als For 100% conformance, you can use the language, `malloc` and `free`, and nothing else. Realistically, there are a lot of functions which will simply never allocate memory (like `memset`); I'd consider them safe as well. Practically, you're probably safe with the entire C library, but my debugging implementations do check for recursion, and do not use more than a `malloc`, `memset` and `memcpy` if `::operator new` is being called recursively (so if `fprintf` does use `::operator new`, I won't end up with infinite recursion). – James Kanze Apr 02 '12 at 08:57