528

I see in C++ there are multiple ways to allocate and free data and I understand that when you call malloc you should call free and when you use the new operator you should pair with delete and it is a mistake to mix the two (e.g. Calling free() on something that was created with the new operator), but I'm not clear on when I should use malloc/ free and when I should use new/ delete in my real world programs.

If you're a C++ expert, please let me know any rules of thumb or conventions you follow in this regard.

JVApen
  • 10,085
  • 3
  • 26
  • 56
  • 34
    Good answers, all I have to add (that I haven't seen) is that new/delete calls the constructor/destructor for you, malloc/free does not. Just a difference worth mentioning. – Bill K Oct 08 '08 at 20:07
  • 38
    I'd just like to add a reminder that you cannot mix the two styles - that is, you cannot use new to create an object and then call free() on it, nor attempt to delete a block allocated by malloc(). Probably obvious to say it, but nonetheless... – nsayer Oct 08 '08 at 19:53
  • 1
    With modern C++, I'm still trying to find a reason to use either. – Rahly Dec 22 '17 at 19:53
  • Or use neither and go with std:shared_ptr. Then you don't have to delete at all. – Vincent Feb 26 '18 at 23:52

19 Answers19

433

Unless you are forced to use C, you should never use malloc. Always use new.

If you need a big chunk of data just do something like:

char *pBuffer = new char[1024];

Be careful though this is not correct:

//This is incorrect - may delete only one element, may corrupt the heap, or worse...
delete pBuffer;

Instead you should do this when deleting an array of data:

//This deletes all items in the array
delete[] pBuffer;

The new keyword is the C++ way of doing it, and it will ensure that your type will have its constructor called. The new keyword is also more type-safe whereas malloc is not type-safe at all.

The only way I could think that would be beneficial to use malloc would be if you needed to change the size of your buffer of data. The new keyword does not have an analogous way like realloc. The realloc function might be able to extend the size of a chunk of memory for you more efficiently.

It is worth mentioning that you cannot mix new/free and malloc/delete.

Note: Some answers in this question are invalid.

int* p_scalar = new int(5);  // Does not create 5 elements, but initializes to 5
int* p_array  = new int[5];  // Creates 5 elements
cmaher
  • 4,454
  • 1
  • 18
  • 33
Brian R. Bondy
  • 314,085
  • 114
  • 576
  • 619
  • 2
    With regard to calling delete foo when you should call delete []foo, some compilers will fix this automagically for you and not leak and other will only delete the first entry and leak. I had a few of these in some code and valgrind will find them for you. – KPexEA Oct 08 '08 at 19:57
  • 1
    I verified this many years ago on VC++ with an array of objects and putting a breakpoint in my destructor. Only the first one got deleted. But ya, good point on some compilers catching this for you. – Brian R. Bondy Oct 08 '08 at 19:58
  • I don't think there's any memory leak if you don't use the [] syntax. But, only the destructor for the first array item will be called. – Ferruccio Oct 08 '08 at 20:10
  • If your compiler doesn't auto convert your delete to delete[] then there is definitely a memory leak. – Brian R. Bondy Oct 08 '08 at 20:12
  • 33
    If you do not use the correct delete **the result is undefined**. It's incorrect. The fact that it might get part of the thing right or work sometimes is just blind luck. – Michael Burr Oct 08 '08 at 23:31
  • I don't think it will cause heap corruption, it will just see it as an pointer to a single element. – Brian R. Bondy Oct 09 '08 at 03:48
  • See items 16.12, 16.14, and 38.7 in the C++ FAQ: http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.12 http://www.parashift.com/c++-faq-lite/compiler-dependencies.html#faq-38.7 – Michael Burr Oct 09 '08 at 04:10
  • 9
    @KPexEA: Even if some compilers might fix your mistakes, it's still wrong to make them in the first place :) Always use delete[] where appropriate. – korona Oct 09 '08 at 08:33
  • 71
    "Unless you are forced to use C, you should never use malloc. Always use new." Why? What is the win here? For objects we need construction, but for memory blocks, you clearly document two ways to make coding mistakes (the more easily caught () vs [] in new and the less easily caught mismatched array vs scaler new and delete). What is the motivation for using new/delete for blocks of raw memory? – Ben Supnik Feb 11 '10 at 20:35
  • 2
    type safe means? Can anyone please elaborate? –  May 05 '11 at 18:23
  • "type safety is the extent to which a programming language discourages or prevents type errors" - wikipedia first line – Niroshan Jun 08 '11 at 16:45
  • 2
    Do not ever, ever use `new[]` and `delete[]`, always use a `std::vector`. – Puppy Dec 21 '11 at 14:11
  • 3
    @DeadMG: If one is creating an array for use by an asynchronous API function, wouldn't `new[]` be much safer than `std::vector`? If one uses `new[]`, the only way the pointer would become invalid would be via explicit `delete`, whereas the memory allocated for an `std::vector` could invalidated when the vector is resized or leaves scope. (Note that when using `new[]` one would have to allow for the possibility that one may not be able to call `delete` if the async method is still pending; if it may be necessary to abandon an async operation, one may have to arrange for delete via callback). – supercat Feb 18 '13 at 16:30
  • What about in the multithreading context with OpenMP for example? Are they equally thread safe? – nullgraph Jan 30 '15 at 20:47
  • 1
    What about `realloc()`?, there is no `renew` – Iharob Al Asimi Apr 23 '15 at 12:43
  • 1
    Actually never use the `new` but prefer it before `malloc` if you really have to use one of them. They both require a manual memory management done by you. Under (almost) all circumstances you have `std::vector` and smart pointers which free the memory when they are destructed. – Marian Spanik Feb 29 '16 at 18:12
  • 1
    `realloc` is a poor reason to prefer `malloc` considering almost everyone calls `realloc` incorrectly. – Paul Coccoli Nov 20 '16 at 00:36
  • another poor reason is calloc – ejectamenta Jan 24 '17 at 13:02
  • 1
    @immibis This is not sufficient? "it will ensure that your type will have their constructor called [...] is also more type safe whereas malloc is not typesafe at all." – IS4 Sep 04 '17 at 22:28
  • Why malloc is not type safe? – scottxiao Apr 23 '18 at 10:57
  • 1
    @PaulCoccoli and the alternative `realloc` for `new` initialized quantities is ? – Carpetfizz Aug 22 '18 at 16:48
  • @Carpetfizz It depends on what those `new` initialized quantities are. As stated multiple times above, there is no `new`-like version of realloc. – Paul Coccoli Aug 23 '18 at 15:33
  • Would this: `int* i = new int{ 5 };` be a better way of initializing it than using round brackets? – Dynamic Squid Aug 13 '20 at 17:19
153

The short answer is: don't use malloc for C++ without a really good reason for doing so. malloc has a number of deficiencies when used with C++, which new was defined to overcome.

Deficiencies fixed by new for C++ code

  1. malloc is not typesafe in any meaningful way. In C++ you are required to cast the return from void*. This potentially introduces a lot of problems:

    #include <stdlib.h>
    
    struct foo {
      double d[5];
    }; 
    
    int main() {
      foo *f1 = malloc(1); // error, no cast
      foo *f2 = static_cast<foo*>(malloc(sizeof(foo)));
      foo *f3 = static_cast<foo*>(malloc(1)); // No error, bad
    }
    
  2. It's worse than that though. If the type in question is POD (plain old data) then you can semi-sensibly use malloc to allocate memory for it, as f2 does in the first example.

    It's not so obvious though if a type is POD. The fact that it's possible for a given type to change from POD to non-POD with no resulting compiler error and potentially very hard to debug problems is a significant factor. For example if someone (possibly another programmer, during maintenance, much later on were to make a change that caused foo to no longer be POD then no obvious error would appear at compile time as you'd hope, e.g.:

    struct foo {
      double d[5];
      virtual ~foo() { }
    };
    

    would make the malloc of f2 also become bad, without any obvious diagnostics. The example here is trivial, but it's possible to accidentally introduce non-PODness much further away (e.g. in a base class, by adding a non-POD member). If you have C++11/boost you can use is_pod to check that this assumption is correct and produce an error if it's not:

    #include <type_traits>
    #include <stdlib.h>
    
    foo *safe_foo_malloc() {
      static_assert(std::is_pod<foo>::value, "foo must be POD");
      return static_cast<foo*>(malloc(sizeof(foo)));
    }
    

    Although boost is unable to determine if a type is POD without C++11 or some other compiler extensions.

  3. malloc returns NULL if allocation fails. new will throw std::bad_alloc. The behaviour of later using a NULL pointer is undefined. An exception has clean semantics when it is thrown and it is thrown from the source of the error. Wrapping malloc with an appropriate test at every call seems tedious and error prone. (You only have to forget once to undo all that good work). An exception can be allowed to propagate to a level where a caller is able to sensibly process it, where as NULL is much harder to pass back meaningfully. We could extend our safe_foo_malloc function to throw an exception or exit the program or call some handler:

    #include <type_traits>
    #include <stdlib.h>
    
    void my_malloc_failed_handler();
    
    foo *safe_foo_malloc() {
      static_assert(std::is_pod<foo>::value, "foo must be POD");
      foo *mem = static_cast<foo*>(malloc(sizeof(foo)));
      if (!mem) {
         my_malloc_failed_handler();
         // or throw ...
      }
      return mem;
    }
    
  4. Fundamentally malloc is a C feature and new is a C++ feature. As a result malloc does not play nicely with constructors, it only looks at allocating a chunk of bytes. We could extend our safe_foo_malloc further to use placement new:

    #include <stdlib.h>
    #include <new>
    
    void my_malloc_failed_handler();
    
    foo *safe_foo_malloc() {
      void *mem = malloc(sizeof(foo));
      if (!mem) {
         my_malloc_failed_handler();
         // or throw ...
      }
      return new (mem)foo();
    }
    
  5. Our safe_foo_malloc function isn't very generic - ideally we'd want something that can handle any type, not just foo. We can achieve this with templates and variadic templates for non-default constructors:

    #include <functional>
    #include <new>
    #include <stdlib.h>
    
    void my_malloc_failed_handler();
    
    template <typename T>
    struct alloc {
      template <typename ...Args>
      static T *safe_malloc(Args&&... args) {
        void *mem = malloc(sizeof(T));
        if (!mem) {
           my_malloc_failed_handler();
           // or throw ...
        }
        return new (mem)T(std::forward(args)...);
      }
    };
    

    Now though in fixing all the issues we identified so far we've practically reinvented the default new operator. If you're going to use malloc and placement new then you might as well just use new to begin with!

Community
  • 1
  • 1
Flexo
  • 82,006
  • 22
  • 174
  • 256
  • 29
    It's too bad C++ made `struct` and `class` mean basically the same thing; I wonder if there would have been any problems with having `struct` be reserved for PODs and possibly having all `class` types be presumed to be non-PODs. Any types defined by code which predated the invention of C++ would necessarily be PODs, so I wouldn't think backward compatibility would be an issue there. Are there advantages to having non-PODs types declared as `struct` rather than `class`? – supercat Feb 18 '13 at 16:15
  • 1
    @supercat A bit late but as it turns out, making `struct` and `class` do almost the same thing was a wonderful design decision that now enables a neat feature called ["metaclasses" (from Herb)](https://herbsutter.com/2017/07/26/metaclasses-thoughts-on-generative-c/). – Rakete1111 Oct 13 '18 at 19:42
  • @Rakete1111: At first glance, that proposal looks like it preprocesses a version of the language that uses dollar-prefixed keywords like `$class`. I'm not sure what that has to do with `class` and `struct` being synonyms, however. – supercat Oct 13 '18 at 19:50
  • @supercat The type system would have been bifurcated more. By having `class` and `struct` mean effectively the same thing, you can do arbitrary transformations on them (`$class`) without worrying of making a `class` a `struct` and vice-versa. – Rakete1111 Oct 13 '18 at 19:54
  • @Rakete1111: If certain kinds of operations and transformations are safe with some types but not others, having the type directly identify that, and having a compiler reject unsafe operations and transformations, would seem better than having a change to a metaclass which was used in ways that are only suitable for a PODS, get silently changed to a non-PODS. – supercat Oct 13 '18 at 19:58
  • @supercat I think I wasn't clear, sorry. What I meant was something akin to `template struct X { T t; };` only being valid for when T is a pod. The same can apply to metaclasses, when do you a transformation on the class that might change it's member in a way that makes the class a pod; either accidentally or not. – Rakete1111 Oct 13 '18 at 20:02
  • @Rakete1111: The requirements for something to be a PODS are a bit stricter than the requirements for presence within a `struct` should be; the biggest requirement should be standard layout. The notion of a `struct` in C was tied to the notion that each `T` occupies a range of `sizeof (T)` consecutive bytes, and a struct is the concatenation of such byte sequences with optional padding, while the notion of "size" is meaningless for class types. – supercat Oct 13 '18 at 21:02
57

From the C++ FQA Lite:

[16.4] Why should I use new instead of trustworthy old malloc()?

FAQ: new/delete call the constructor/destructor; new is type safe, malloc is not; new can be overridden by a class.

FQA: The virtues of new mentioned by the FAQ are not virtues, because constructors, destructors, and operator overloading are garbage (see what happens when you have no garbage collection?), and the type safety issue is really tiny here (normally you have to cast the void* returned by malloc to the right pointer type to assign it to a typed pointer variable, which may be annoying, but far from "unsafe").

Oh, and using trustworthy old malloc makes it possible to use the equally trustworthy & old realloc. Too bad we don't have a shiny new operator renew or something.

Still, new is not bad enough to justify a deviation from the common style used throughout a language, even when the language is C++. In particular, classes with non-trivial constructors will misbehave in fatal ways if you simply malloc the objects. So why not use new throughout the code? People rarely overload operator new, so it probably won't get in your way too much. And if they do overload new, you can always ask them to stop.

Sorry, I just couldn't resist. :)

Matthias Benkard
  • 14,907
  • 2
  • 36
  • 46
  • 8
    I cannot take this comment serious as it clearly projects the author's biased against C++. C++ is a language used to create performance oriented software, and a garbage collector could only be detrimental to its objective. I disagree with your entire answer! – Miguel Nov 26 '15 at 21:23
  • 1
    @Miguel You missed the joke. – Dan Bechard Apr 11 '16 at 17:29
52

Always use new in C++. If you need a block of untyped memory, you can use operator new directly:

void *p = operator new(size);
   ...
operator delete(p);
Ferruccio
  • 93,779
  • 37
  • 217
  • 294
40

new vs malloc()

1) new is an operator, while malloc() is a function.

2) new calls constructors, while malloc() does not.

3) new returns exact data type, while malloc() returns void *.

4) new never returns a NULL (will throw on failure) while malloc() returns NULL

5) Reallocation of memory not handled by new while malloc() can

Yogeesh H T
  • 2,093
  • 18
  • 17
  • 6
    Hi , For point 4) , new can be instructed to return NULL on failure. `char* ptr = new (std::nothrow) char [323232];` – Singh Oct 07 '16 at 08:54
  • 1
    6) new creates from constructor arguments, while malloc uses size. – Evan Moran Oct 16 '16 at 15:03
  • there is also a `new` function – Ma Ming Oct 18 '17 at 09:06
  • If you were so inclined in C as to *reallocate*, I would hope that you'd use `realloc` rather than `malloc`, and start off with your pointer variable initialised to `NULL`. If you want a *resizable* chunk of memory in C++, on the other hand, I would be suggesting `std::vector` as opposed to `realloc`... That or a file. – autistic Apr 29 '18 at 16:35
33

Use malloc and free only for allocating memory that is going to be managed by c-centric libraries and APIs. Use new and delete (and the [] variants) for everything that you control.

dmckee --- ex-moderator kitten
  • 90,531
  • 23
  • 129
  • 225
  • 11
    Also notice that well written C library will hide malloc and free internally, this is how the C programmer should work. – Dacav Aug 13 '10 at 18:26
  • @dmckee do you have an example of C++ using c-centric libraries by malloc and free? – milesma Jul 31 '13 at 00:44
  • 2
    @Dacav: If a C function will accept a pointer to an object that it will need to keep using after the function returns, and the caller will have no way of knowing when the object is still needed, it would be perfectly reasonable for the function to specify that the pointer must have been created with `malloc`. Likewise if a function like `strdup` needs to create an object and return it to a caller, it is perfectly reasonable to specify that the caller must call `free` on the object when it is no longer needed. How could such functions avoid exposing their use of malloc/free to the caller? – supercat Apr 06 '15 at 17:09
  • @supercat, there's something inherently wrong in having a C function accept a pointer to objects, since C is not aware of objects at all. In general I believe the best approach is having semantic wrappers around allocation/deallocation also in C. It can be still acceptable, but less flexible, if a C library is asking the caller to pre-allocate and/or deallocate memory. If a C function is doing this and claiming ownership on the allocated memory, you are implicitly required to allocate it with malloc. – Dacav Apr 06 '15 at 20:30
  • @supercat One example of an every-day package which I'm sure everyone has used is libgmp. If you've ever used any open-source encryption or software based on such encryption (which is very likely) then you've probably used an arbitrary precision arithmetic library which needs to grow and shrink its own internal data. This is done using an initialisation function... and then you gotta wonder, how do you use the C code which is libgmp, in C++, without recompiling it in C++? Now with that (the linker) in mind, think about it... why would any sensible person *ever* put `malloc` in C++? – autistic Apr 29 '18 at 15:41
  • @Sebivor: The C Standard overloads the term "object" for a number of different but related concepts which differ from how it's used in other contexts. – supercat Apr 29 '18 at 15:50
  • I think that Dacav is suggesting that c libraries implementing opaque types ought to offer a facility for initializing the opaque storage so that the details of who those objects are managed internally are completely hidden and the caller doesn't even have to know what memory management scheme is used internally. But however you feel about that prescription, there are many places where the caller is expected to do the allocation (starting with unix `FILE`s). – dmckee --- ex-moderator kitten Apr 29 '18 at 15:53
  • Sebivor: I think, though, perhaps you meant your comment for @Decav? – supercat Apr 29 '18 at 15:53
  • [I meant @Dacav] – supercat Apr 29 '18 at 15:54
  • @dmckee: It was Dacav that said that C is not aware of objects at all. Neither the C core language nor the Standard Library has a broad-reaching concept of functions that create persistent storage or entities as part of their operation, other than those whose purpose is to create such entities (e.g. malloc, fopen, etc.); all other functions that operate on such entities expect them to have been created by their caller, either by using functions whose sole purpose was such creation, or by such means as the caller sees fit. – supercat Apr 29 '18 at 16:00
  • @Sebivor: The C Standard overloads the term to describe variables, struct members, union members, array elements, malloc-allocated regions, and pointer targets, which leads to problems in places like e.g. 6.5p7 which limits the cases where an "object" can have its stored value accessed. – supercat Apr 29 '18 at 16:04
  • @supercat I assume the C++ standard inherits the C standards definition, since it doesn't otherwise seem to have one, and for every C++ compiler I've ever used there's been a compatible C ABI, which includes things like structure layout and internal representation of types. Additionally, the C++ standard actually talks about basic types like arrays of characters as though *they* are objects. – autistic Apr 29 '18 at 16:12
  • Wait, no, C++ **does** have a definition for "object". It says it plain and clear... "An object is a region of storage." – autistic Apr 29 '18 at 16:15
  • 1
    @Dacav From the C++ standard, the section entited [The C++ object model](http://cpp14.centaur.ath.cx/intro.object.html), we can see a definition for *object*: *"An object is a region of storage."* There's a similar definition in the C standard; `char c;` in both C and C++, this variable denotes an object. The difference is that *some* (but not all) objects in C++ are *also* polymorphic (because C++ is OO, after all). Don't make the mistake of believing only object oriented code can use objects. – autistic Apr 29 '18 at 16:25
  • @Sebivor, these messages are quite old, is this comment thread still alive? At any rate, I'm using object-oriented design for C programs as well, so I totally agree with you – Dacav Apr 29 '18 at 19:50
  • @Dacav Really? If you design a function which requires a specific form of allocation (and forces the rest of the world to use that allocation when called upon), that's technically a violation of dependency inversion principle, one of the five core principles of object oriented design. Not everything you can do in C++ is object oriented, and there isn't a whole lot you can do with pure object oriented constructs. You can't compose logic (sequence, selection and iteration) without (typically) procedural or functional constructs. OO is just a more specific form of one of those with extensions. – autistic Apr 30 '18 at 04:45
32

To answer your question, you should know the difference between malloc and new. The difference is simple:

malloc allocates memory, while new allocates memory AND calls the constructor of the object you're allocating memory for.

So, unless you're restricted to C, you should never use malloc, especially when dealing with C++ objects. That would be a recipe for breaking your program.

Also the difference between free and delete is quite the same. The difference is that delete will call the destructor of your object in addition to freeing memory.

The Quantum Physicist
  • 21,050
  • 13
  • 77
  • 143
15

There is one big difference between malloc and new. malloc allocates memory. This is fine for C, because in C, a lump of memory is an object.

In C++, if you're not dealing with POD types (which are similar to C types) you must call a constructor on a memory location to actually have an object there. Non-POD types are very common in C++, as many C++ features make an object automatically non-POD.

new allocates memory and creates an object on that memory location. For non-POD types this means calling a constructor.

If you do something like this:

non_pod_type* p = (non_pod_type*) malloc(sizeof *p);

The pointer you obtain cannot be dereferenced because it does not point to an object. You'd need to call a constructor on it before you can use it (and this is done using placement new).

If, on the other hand, you do:

non_pod_type* p = new non_pod_type();

You get a pointer that is always valid, because new created an object.

Even for POD types, there's a significant difference between the two:

pod_type* p = (pod_type*) malloc(sizeof *p);
std::cout << p->foo;

This piece of code would print an unspecified value, because the POD objects created by malloc are not initialised.

With new, you could specify a constructor to call, and thus get a well defined value.

pod_type* p = new pod_type();
std::cout << p->foo; // prints 0

If you really want it, you can use use new to obtain uninitialised POD objects. See this other answer for more information on that.

Another difference is the behaviour upon failure. When it fails to allocate memory, malloc returns a null pointer, while new throws an exception.

The former requires you to test every pointer returned before using it, while the later will always produce valid pointers.

For these reasons, in C++ code you should use new, and not malloc. But even then, you should not use new "in the open", because it acquires resources you need to release later on. When you use new you should pass its result immediately into a resource managing class:

std::unique_ptr<T> p = std::unique_ptr<T>(new T()); // this won't leak
Community
  • 1
  • 1
R. Martinho Fernandes
  • 209,766
  • 68
  • 412
  • 492
10

Dynamic allocation is only required when the life-time of the object should be different than the scope it gets created in (This holds as well for making the scope smaller as larger) and you have a specific reason where storing it by value doesn't work.

For example:

 std::vector<int> *createVector(); // Bad
 std::vector<int> createVector();  // Good

 auto v = new std::vector<int>(); // Bad
 auto result = calculate(/*optional output = */ v);
 auto v = std::vector<int>(); // Good
 auto result = calculate(/*optional output = */ &v);

From C++11 on, we have std::unique_ptr for dealing with allocated memory, which contains the ownership of the allocated memory. std::shared_ptr was created for when you have to share ownership. (you'll need this less than you would expect in a good program)

Creating an instance becomes really easy:

auto instance = std::make_unique<Class>(/*args*/); // C++14
auto instance = std::unique_ptr<Class>(new Class(/*args*/)); // C++11
auto instance = std::make_unique<Class[]>(42); // C++14
auto instance = std::unique_ptr<Class[]>(new Class[](42)); // C++11

C++17 also adds std::optional which can prevent you from requiring memory allocations

auto optInstance = std::optional<Class>{};
if (condition)
    optInstance = Class{};

As soon as 'instance' goes out of scope, the memory gets cleaned up. Transferring ownership is also easy:

 auto vector = std::vector<std::unique_ptr<Interface>>{};
 auto instance = std::make_unique<Class>();
 vector.push_back(std::move(instance)); // std::move -> transfer (most of the time)

So when do you still need new? Almost never from C++11 on. Most of the you use std::make_unique until you get to a point where you hit an API that transfers ownership via raw pointers.

 auto instance = std::make_unique<Class>();
 legacyFunction(instance.release()); // Ownership being transferred

 auto instance = std::unique_ptr<Class>{legacyFunction()}; // Ownership being captured in unique_ptr

In C++98/03, you have to do manual memory management. If you are in this case, try upgrading to a more recent version of the standard. If you are stuck:

 auto instance = new Class(); // Allocate memory
 delete instance;             // Deallocate
 auto instances = new Class[42](); // Allocate memory
 delete[] instances;               // Deallocate

Make sure that you track the ownership correctly to not have any memory leaks! Move semantics don't work yet either.

So, when do we need malloc in C++? The only valid reason would be to allocate memory and initialize it later via placement new.

 auto instanceBlob = std::malloc(sizeof(Class)); // Allocate memory
 auto instance = new(instanceBlob)Class{}; // Initialize via constructor
 instance.~Class(); // Destroy via destructor
 std::free(instanceBlob); // Deallocate the memory

Even though, the above is valid, this can be done via a new-operator as well. std::vector is a good example for this.

Finally, we still have the elephant in the room: C. If you have to work with a C-library where memory gets allocated in the C++ code and freed in the C code (or the other way around), you are forced to use malloc/free.

If you are in this case, forget about virtual functions, member functions, classes ... Only structs with PODs in it are allowed.

Some exceptions to the rules:

  • You are writing a standard library with advanced data structures where malloc is appropriate
  • You have to allocate big amounts of memory (In memory copy of a 10GB file?)
  • You have tooling preventing you to use certain constructs
  • You need to store an incomplete type
JVApen
  • 10,085
  • 3
  • 26
  • 56
6

There are a few things which new does that malloc doesn’t:

  1. new constructs the object by calling the constructor of that object
  2. new doesn’t require typecasting of allocated memory.
  3. It doesn’t require an amount of memory to be allocated, rather it requires a number of objects to be constructed.

So, if you use malloc, then you need to do above things explicitly, which is not always practical. Additionally, new can be overloaded but malloc can’t be.

herohuyongtao
  • 45,575
  • 23
  • 118
  • 159
5

If you work with data that doesn't need construction/destruction and requires reallocations (e.g., a large array of ints), then I believe malloc/free is a good choice as it gives you realloc, which is way faster than new-memcpy-delete (it is on my Linux box, but I guess this may be platform dependent). If you work with C++ objects that are not POD and require construction/destruction, then you must use the new and delete operators.

Anyway, I don't see why you shouldn't use both (provided that you free your malloced memory and delete objects allocated with new) if can take advantage of the speed boost (sometimes a significant one, if you're reallocing large arrays of POD) that realloc can give you.

Unless you need it though, you should stick to new/delete in C++.

PSkocik
  • 52,186
  • 6
  • 79
  • 122
3

If you have C code you want to port over to C++, you might leave any malloc() calls in it. For any new C++ code, I'd recommend using new instead.

Fred Larson
  • 56,061
  • 15
  • 106
  • 157
3

If you are using C++, try to use new/delete instead of malloc/calloc as they are operators. For malloc/calloc, you need to include another header. Don't mix two different languages in the same code. Their work is similar in every manner, both allocates memory dynamically from heap segment in hash table.

Pang
  • 8,605
  • 144
  • 77
  • 113
2

new will initialise the default values of the struct and correctly links the references in it to itself.

E.g.

struct test_s {
    int some_strange_name = 1;
    int &easy = some_strange_name;
}

So new struct test_s will return an initialised structure with a working reference, while the malloc'ed version has no default values and the intern references aren't initialised.

kungfooman
  • 3,696
  • 1
  • 32
  • 25
1

From a lower perspective, new will initialize all the memory before giving the memory whereas malloc will keep the original content of the memory.

Peiti Li
  • 3,386
  • 7
  • 29
  • 45
  • 4
    new does not in general initialize memory, although there are ways to make that happen: see http://stackoverflow.com/questions/2204176/how-to-initialise-memory-with-new-operator-in-c for one discussion about it. – wjl Sep 30 '11 at 14:54
0

In the following scenario, we can't use new since it calls constructor.

class  B  {
private:
    B *ptr;
    int x;
public:
    B(int n)  {
        cout<<"B: ctr"<<endl;
        //ptr = new B;  //keep calling ctr, result is segmentation fault
        ptr = (B *)malloc(sizeof(B));
        x = n;
        ptr->x = n + 10;
    }
    ~B()  {
        //delete ptr;
        free(ptr);
        cout<<"B: dtr"<<endl;
    }
};
moribvndvs
  • 40,946
  • 9
  • 129
  • 143
Barry
  • 29
  • 2
0

The new and delete operators can operate on classes and structures, whereas malloc and free only work with blocks of memory that need to be cast.

Using new/delete will help to improve your code as you will not need to cast allocated memory to the required data structure.

hackjutsu
  • 6,728
  • 10
  • 39
  • 73
selwyn
  • 1,136
  • 2
  • 9
  • 19
0

Rare case to consider using malloc/free instead of new/delete is when you're allocating and then reallocating (simple pod types, not objects) using realloc as there is no similar function to realloc in C++ (although this can be done using a more C++ approach).

Pang
  • 8,605
  • 144
  • 77
  • 113
-4

malloc() is used to dynamically assign memory in C while the same work is done by new() in c++. So you cannot mix coding conventions of 2 languages. It would be good if you asked for difference between calloc and malloc()

  • 2
    You *can* (but almost always shouldn't) use `malloc` in C++. – interjay Jul 26 '12 at 13:06
  • 1
    You also missed the prime point that you should aim to avoid dynamic memory allocation, unless doing so through smart pointers. You are just setting your self up for pain other wise – thecoshman Oct 11 '12 at 10:55