Custom allocator including placement new case - c++

I'm trying to implement a custom allocator for C++ that works on any form of new/delete/malloc/free. How my program works, I allocate at the start of the program a memory pool of x bytes and work with them. For example, when someone writes int* a= new int; my program will return the address from the memory pool which is available and marks it as allocated and that address along with the size allocated is removed from the memory pool. When someone writes delete a; the address is returned to the memory pool and can be used again. My problem is that I don't fully understand how new(placement) works and how should I deal with it, because when my function gets called to allocate memory on new/malloc I have as a parameter only the size of the memory the program needs and I just return an available address to that memory to be used. Consider the following example
auto p = (std::string*)malloc(5 * sizeof(std::string));
void * placement = p;
new(placement) std::string(4, (char)('a'));
std::cout<< *p;
On the first line my custom allocated will return to p an address from my memory pool where there is memory available of a total of 5* sizeof(std::string)), on the third line my custom allocator will allocate again memory returning another address. When I print *p it prints exactly what I was expected aaaa.
Is this how it should work?

A normal new does two things:
allocate storage; and
construct an object.
Now we want to separate these two steps. Allocating raw storage is easy, but there is no "native" way to construct an object at a given address in C++. Therefore, the new operator is overloaded to serve this purpose, by returning the given pointer for the first step.
We don't need a corresponding delete, because we can call the destructor manually. In C++17, std::destroy_at was added to the standard library. Since C++20, std::construct_at can be used to construct an object instead of placement new:
std::construct_at(p, 4, 'a');
The C++ Super-FAQ explains placement new very well:
What is “placement new” and why would I use it?
There are many uses of placement new. The simplest use is to place an
object at a particular location in memory. This is done by supplying
the place as a pointer parameter to the new part of a new expression:
#include <new> // Must #include this to use "placement new"
#include "Fred.h" // Declaration of class Fred
void someCode()
{
char memory[sizeof(Fred)]; // Line #1
void* place = memory; // Line #2
Fred* f = new(place) Fred(); // Line #3 (see "DANGER" below)
// The pointers f and place will be equal
// ...
}
Line #1 creates an array of sizeof(Fred) bytes of memory, which is
big enough to hold a Fred object. Line #2 creates a pointer place
that points to the first byte of this memory (experienced C
programmers will note that this step was unnecessary; it’s there only
to make the code more obvious). Line #3 essentially just calls the
constructor Fred::Fred(). The this pointer in the Fred
constructor will be equal to place. The returned pointer f will
therefore be equal to place.
ADVICE: Don’t use this “placement new” syntax unless you have to. Use it only when you really care that an object is placed at a
particular location in memory. For example, when your hardware has a
memory-mapped I/O timer device, and you want to place a Clock object
at that memory location.
DANGER: You are taking sole responsibility that the pointer you pass to the “placement new” operator points to a region of memory that is
big enough and is properly aligned for the object type that you’re
creating. Neither the compiler nor the run-time system make any
attempt to check whether you did this right. If your Fred class
needs to be aligned on a 4 byte boundary but you supplied a location
that isn’t properly aligned, you can have a serious disaster on your
hands (if you don’t know what “alignment” means, please don’t use
the placement new syntax). You have been warned.
You are also solely responsible for destructing the placed object.
This is done by explicitly calling the destructor:
void someCode()
{
char memory[sizeof(Fred)];
void* p = memory;
Fred* f = new(p) Fred();
// ...
f->~Fred(); // Explicitly call the destructor for the placed object
}
This is about the only time you ever explicitly call a destructor.

Related

std::list as struct member not initialised [duplicate]

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 <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
}
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.
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;
}
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();
}
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!
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);
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
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.
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.
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
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.
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.
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.
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).
I had played before with few C/C++ applications for computer graphics.
After so many time, some things are vanished and I missed them a lot.
The point is, that malloc and new, or free and delete, can work both,
especially for certain basic types, which are the most common.
For instance, a char array, can be allocated both with malloc, or new.
A main difference is, with new you can instantiate a fixed array size.
char* pWord = new char[5]; // allocation of char array of fixed size
You cannot use a variable for the size of the array in this case.
By the contrary, the malloc function could allow a variable size.
int size = 5;
char* pWord = (char*)malloc(size);
In this case, it might be required a conversion cast operator.
For the returned type from malloc it's a pointer to void, not char.
And sometimes the compiler could not know, how to convert this type.
After allocation the memory block, you can set the variable values.
the memset function can be indeed slower for some bigger arrays.
But all the bites must be set first to 0, before assigning a value.
Because the values of an array could have an arbitrary content.
Suppose, the array is assigned with another array of smaller size.
Part of the array element could still have arbitrary content.
And a call to a memset function would be recomended in this case.
memset((void*)pWord, 0, sizeof(pWord) / sizeof(char));
The allocation functions are available for all C packages.
So, these are general functions, that must work for more C types.
And the C++ libraries are extensions of the older C libraries.
Therefore the malloc function returns a generic void* pointer.
The sructures do not have defined a new, or a delete operator.
In this case, a custom variable can be allocated with malloc.
The new and delete keywords are actually some defined C operators.
Maybe a custom union, or class, can have defined these operators.
If new and delete are not defined in a class, these may not work.
But if a class is derived from another, which has these operators,
the new and delete keywords can have the basic class behavior.
About freeing an array, free can be only used in pair with malloc.
Cannot allocate a variable with malloc, and then free with delete.
The simple delete operator references just first item of an array.
Because the pWord array can be also written as:
pWord = &pWord[0]; // or *pWord = pWord[0];
When an array must be deleted, use the delete[] operator instead:
delete[] pWord;
Casts are not bad, they just don't work for all the variable types.
A conversion cast is also an operator function, that must be defined.
If this operator is not defined for a certain type, it may not work.
But not all the errors are because of this conversion cast operator.
Also a cast to a void pointer must be used when using a free call.
This is because the argument of the free function is a void pointer.
free((void*)pWord);
Some errors can arise, because the size of the array is too small.
But this is another story, it is not because of using the cast.
With kind regards, Adrian Brinas
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()

Why does adding a string to a struct cause a crash (when mallocing) [duplicate]

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 <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
}
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.
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;
}
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();
}
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!
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);
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
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.
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.
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
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.
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.
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.
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).
I had played before with few C/C++ applications for computer graphics.
After so many time, some things are vanished and I missed them a lot.
The point is, that malloc and new, or free and delete, can work both,
especially for certain basic types, which are the most common.
For instance, a char array, can be allocated both with malloc, or new.
A main difference is, with new you can instantiate a fixed array size.
char* pWord = new char[5]; // allocation of char array of fixed size
You cannot use a variable for the size of the array in this case.
By the contrary, the malloc function could allow a variable size.
int size = 5;
char* pWord = (char*)malloc(size);
In this case, it might be required a conversion cast operator.
For the returned type from malloc it's a pointer to void, not char.
And sometimes the compiler could not know, how to convert this type.
After allocation the memory block, you can set the variable values.
the memset function can be indeed slower for some bigger arrays.
But all the bites must be set first to 0, before assigning a value.
Because the values of an array could have an arbitrary content.
Suppose, the array is assigned with another array of smaller size.
Part of the array element could still have arbitrary content.
And a call to a memset function would be recomended in this case.
memset((void*)pWord, 0, sizeof(pWord) / sizeof(char));
The allocation functions are available for all C packages.
So, these are general functions, that must work for more C types.
And the C++ libraries are extensions of the older C libraries.
Therefore the malloc function returns a generic void* pointer.
The sructures do not have defined a new, or a delete operator.
In this case, a custom variable can be allocated with malloc.
The new and delete keywords are actually some defined C operators.
Maybe a custom union, or class, can have defined these operators.
If new and delete are not defined in a class, these may not work.
But if a class is derived from another, which has these operators,
the new and delete keywords can have the basic class behavior.
About freeing an array, free can be only used in pair with malloc.
Cannot allocate a variable with malloc, and then free with delete.
The simple delete operator references just first item of an array.
Because the pWord array can be also written as:
pWord = &pWord[0]; // or *pWord = pWord[0];
When an array must be deleted, use the delete[] operator instead:
delete[] pWord;
Casts are not bad, they just don't work for all the variable types.
A conversion cast is also an operator function, that must be defined.
If this operator is not defined for a certain type, it may not work.
But not all the errors are because of this conversion cast operator.
Also a cast to a void pointer must be used when using a free call.
This is because the argument of the free function is a void pointer.
free((void*)pWord);
Some errors can arise, because the size of the array is too small.
But this is another story, it is not because of using the cast.
With kind regards, Adrian Brinas
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()

What does "new (&variable) value;" in C++ do?

Say I have the following code in a C++ program:
Object a = Object(someParameters);
new (&a) Object(someOtherParameters);
My assumption is that it replaces the contents of a with Object(someOtherParameters), avoiding a possible operator= declared for Object. Is this correct?
It's called placement new. It calles the constructor on the specified memory rather than allocating new memory. Note that in this case you have to explicitly call the destructor of your object before freeing the allocated memory.
Clarification. Suppose you have allocated some raw memory
char * rawMemory = new char [sizeof (Object)];
and you want to construct an object on that memory. You call
new(rawMemory) Object(params);
Now, before freeing the memory
delete [] rawMemory;
you will have to call the derstuctor of Object explicitly
reinterpret_cast<Object*>(rawMemory)->~Object();
In your particular example, however, the potential problem is that you haven't properly destroyed the existing object before constructing a new one in its memory.
Bonus:
Ever wondered how standard std::vector can do without its contained objects being default-constructible? The reason is that on most, if not all, implementations allocator<T> does not store a T* p which would require T to be default-constructible in case of p = new T[N]. Instead it stores a char pointer - raw memory, and allocates p = new char[N*sizeof(T)]. When you push_back an object, it just calls the copy constructor with placement new on the appropriate address in that char array.
It's known as placement new: it constructs the new Object at the address given inside the parentheses. Placement new is usually used to create an object in raw memory. Constructing a new object on top of an existing one, as this code does, is a bad idea, because it doesn't call the destructor on the original object.

Should I use delete or delete[] when receiving either a dynamic array or heap object?

Say I have two items on the heap:
Foo *f = new Foo;
Foo *g = new Foo[42];
And say I have a function that receives a Foo pointer and within the function it needs to perform a delete:
void bar(Foo *p) {
// some stuff
delete p;
}
This function might be called like so:
bar(f); // passing a pointer to a Foo object on the heap
bar(g); // passing a pointer to an array on the heap
I recognize that delete[] and delete should be used to free memory allocated with new[] and new respectively; However since the function doesn't know if its parameter p was allocated with new or new[], how can this function properly delete or delete[]?
It sounds like you have a problem with the Single Responsibility Principle.
You have some amount of processing that operates on a single object, so it's reasonable to pass an individual object or an array. (Why isn't that processing also useful for an array element other than the first, or a non-dynamic object?)
And then you have to free the object. Or the array.
There are three different tasks here, which calls for three different functions.
Essentially, if "the function doesn't know if its parameter p was allocated with new or new[]", that function has no business trying to deallocate. What if the parameter is on the stack? What if a pooled allocator was used?
Also, once the processing is moved to a separate function, it becomes easy to make a function for "process then delete single object" and also "process then delete array" without duplication (both call the helper function for the processing component).
You can't (portably) detect that and do the right thing in the function.
A "workaround" would be to use std::vector<Foo> instead of the array, and just always use delete.
Solution 1. From a code design point of view, you should probably avoid cases like this altogether, and have the object be deleted by the same class, pair of create-destroy functions, or code block that allocated it. This way, you know you're not making any mistakes.
Solution 2. If you compiler supports them, use std::shared_ptr and lambda functions, and use a different deallocator for each pointer, as appropriate. Read about shared pointers here.
std::shared_ptr<Foo> f(new Foo[20], [](Foo* p) { delete[] p; });
std::shared_ptr<Foo> g(new Foo);
The first one, f is a shared pointer to an array. When I create it, I give as the first parameter a (normal) pointer to the array; the second parameter is a lambda function that takes a Foo* p parameter and its body is { delete[] p; }.
By default, std::shared_ptr uses delete to deallocate memory. This is why, when I create the second one, I only give it the pointer to the object and don't specify any custom deallocator.
You can't. You never know if a pointer points to an object or an array of such object.
But, if you really want to have a single function for deallocation, and if you can ever ever remember to allocate anything like an array even if you're allocating one object, the following use is legal:
Foo *h = new Foo[0];
Foo *f = new Foo[1];
Foo *g = new Foo[42];
void bar(Foo *p) {
// some stuff
delete [] p;
}
However, remember that sometimes technically possible doesn't mean that you should use it. That depends on your use case whether it makes sense to treat an object as a special case of an array.
The more elegant C++ way is to use std::vector or boost::scoped_ptr, boost::scoped_array, etc, which guarantee to call correct version of delete operator, just as their names indicate.
You have to pass which it is. The function can't determine that at runtime.
See here for a good explanation.
It's up to the compiler vendor to decide how this should be implemented, and as such falls under the "magic" category.
In general though, the runtime will allocate an extra additional 4 bytes when you use new[]. Then it will store the size of the array in these bytes, and return the allocation + 4 bytes. When deallocating, it will remove 4 from the pointer you passed it, read the size and use that to decide how many destructors etc. to call.
You can read more about this in the C++ FAQ

In what cases do I use malloc and/or new?

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 <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
}
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.
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;
}
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();
}
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!
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);
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
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.
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.
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
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.
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.
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.
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).
I had played before with few C/C++ applications for computer graphics.
After so many time, some things are vanished and I missed them a lot.
The point is, that malloc and new, or free and delete, can work both,
especially for certain basic types, which are the most common.
For instance, a char array, can be allocated both with malloc, or new.
A main difference is, with new you can instantiate a fixed array size.
char* pWord = new char[5]; // allocation of char array of fixed size
You cannot use a variable for the size of the array in this case.
By the contrary, the malloc function could allow a variable size.
int size = 5;
char* pWord = (char*)malloc(size);
In this case, it might be required a conversion cast operator.
For the returned type from malloc it's a pointer to void, not char.
And sometimes the compiler could not know, how to convert this type.
After allocation the memory block, you can set the variable values.
the memset function can be indeed slower for some bigger arrays.
But all the bites must be set first to 0, before assigning a value.
Because the values of an array could have an arbitrary content.
Suppose, the array is assigned with another array of smaller size.
Part of the array element could still have arbitrary content.
And a call to a memset function would be recomended in this case.
memset((void*)pWord, 0, sizeof(pWord) / sizeof(char));
The allocation functions are available for all C packages.
So, these are general functions, that must work for more C types.
And the C++ libraries are extensions of the older C libraries.
Therefore the malloc function returns a generic void* pointer.
The sructures do not have defined a new, or a delete operator.
In this case, a custom variable can be allocated with malloc.
The new and delete keywords are actually some defined C operators.
Maybe a custom union, or class, can have defined these operators.
If new and delete are not defined in a class, these may not work.
But if a class is derived from another, which has these operators,
the new and delete keywords can have the basic class behavior.
About freeing an array, free can be only used in pair with malloc.
Cannot allocate a variable with malloc, and then free with delete.
The simple delete operator references just first item of an array.
Because the pWord array can be also written as:
pWord = &pWord[0]; // or *pWord = pWord[0];
When an array must be deleted, use the delete[] operator instead:
delete[] pWord;
Casts are not bad, they just don't work for all the variable types.
A conversion cast is also an operator function, that must be defined.
If this operator is not defined for a certain type, it may not work.
But not all the errors are because of this conversion cast operator.
Also a cast to a void pointer must be used when using a free call.
This is because the argument of the free function is a void pointer.
free((void*)pWord);
Some errors can arise, because the size of the array is too small.
But this is another story, it is not because of using the cast.
With kind regards, Adrian Brinas
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()