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.
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
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
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
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
?
struct
and class
do almost the same thing was a wonderful design decision that now enables a neat feature called "metaclasses" (from Herb).
$class
. I'm not sure what that has to do with class
and struct
being synonyms, however.
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.
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. :)
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);
operator new
is operator delete
. It is not a well defined action to call delete
on an expression with type void*
.
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
char* ptr = new (std::nothrow) char [323232];
new
function
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.
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.
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?
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.
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.
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
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
malloc
or new
calls.
There are a few things which new
does that malloc
doesn’t:
new constructs the object by calling the constructor of that object new doesn’t require typecasting of allocated memory. 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.
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++.
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.
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.
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.
From a lower perspective, new will initialize all the memory before giving the memory whereas malloc will keep the original content of the memory.
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;
}
};
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).
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.
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()
malloc
in C++.
Success story sharing
new[]
be much safer thanstd::vector
? If one usesnew[]
, the only way the pointer would become invalid would be via explicitdelete
, whereas the memory allocated for anstd::vector
could invalidated when the vector is resized or leaves scope. (Note that when usingnew[]
one would have to allow for the possibility that one may not be able to calldelete
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).