C++ Deallocate exact size of memory - c++

I've thought about how I can improve the performance of reading of a list sort by an (unsigned) integer that is read in at the program start and won't change until the program exits. I thought about different possibilities but then I got an idea and I'd like to know if that's possible and if not, why not - because in my theory it should be possible for the computer.
I have a list with something like 10.000 entries, every entry has an unique ID (an the unique ID is not 0). Now what about allocating memory with the size object* pList = new(sizeof(object) * max_unique_id) and then deleting all the unused memory (check what unique id is not existing and free the memory at the position with the size sizeof(object))... you would be using only the needed memory and you could just access to a list entry with pList[unique_id] -> would be really, really fast... but you cannot delete a single element in a dynamic allocated array :/ At the program termination you can of course free all the elements, it's no problem to safe the pointer + sizes in a std::vector or sth like that.
That's why I'm asking if my theory is incorrect or if the system just does not allow it or where the problem is.

No, you can't control memory like that. However, it IS possible to cheat a little bit. If you are allocating big chunks of memory, you can make your own memory pool. That way, you can create the holes yourself and use that memory for other parts of your program.
I wouldn't recommend it though, as you may have issues with strict aliasing, as well as having to deal with more complexity in your code.
Rewinding just a little, you are forgetting about caching effects, which are significant. Keeping your objects packed closely together will likely have more effect on speed than making the lookup faster.
To achieve this you could use a simple hash to look up your objects, or you could just make a sparse index array of 16-bit indices.

You can, (though I have no idea why you want to), but you will have to write it as your own custom memory allocation and deallocation routine or class. Using the standard C++ library out of the box, you can't.
See some of the interfaces for allocating memory in C++
void* operator new ( std::size_t );
void* operator new[]( std::size_t );
void* operator new ( std::size_t, const std::nothrow_t&);
void* operator new[]( std::size_t, const std::nothrow_t&);
Taking void* operator new[]( std::size_t ); for example. There is absolutely no way the this routine knows how many objects are stored in the memory region that will be returned.
Same with it's matching function
void operator delete[]( void* ptr );
it only takes a void pointer, there is absolutely no way it knows how many you want to delete. The memory allocator that provided memory starting with that block pointed by ptr magically knows the size it allocated, and hence deletes it appropriately

Use placement new.
object* pList = new(sizeof(object) * max_unique_id)
Do not do this. new is NOT malloc. But you also cannot do this instead:
object* pList = new object[max_unique_id];
delete object[1];
C++ does not allow to delete individually allocated elements of a dyanmically allocated array with a simple delete.
C++ allows you to create an object in a pre-allocated memory space by using placement new. In this case, you must manually call the constructor with a call to placement new and the destructor.
Reference: Malloc and constructors
A* a = (A*)malloc(sizeof(A));
new (a) A();
a->~A();
free(a);
In other words, supply the exact place where you want a specific object to be created. I would suggest that you use a loop:
// Allocate the space using malloc()
object* pList = std::malloc(sizeof(object) * max_unique_id);
// Allocate using a loop. I would not trust a parallelization of this code.
// Doing memory allocation in parallel without the proper locks and stuff
// is probably wrong.
for (auto i = 0; i < max_unique_id; ++i) {
// Supply the point as the argument to placement new.
new (&pList[i]) object(/* arguments go here */);
}
Then, when you're done using a certain object, say i = 20...
// Select the object
object* todelete_object = pList[i];
// Manually call the destructor.
todelete_object->~object()
// Now, free the memory.
std::free(todelete_object);
I use std::malloc() and std::free() as defined in the C++-style C standard library includes.

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()

In C++, what is the difference between new and new[] for array allocations

I am aware of the differences between free and delete in C++. But one thing I never understood is why in C malloc/free can allocate de-allocate both single 'objects' and arrays but in C++ we need to use the correct new/delete vs new[]/delete[] pair.
Searching on Stackoverflow, it seems that in C++, new[] allocates extra memory to hold the size of the allocated array and new only allocates the memory to the object itself. And because of that, you should be aware of this extra overhead.
If the previous paragraph is indeed the case, then how malloc/free handles this overhead? Or they just accept this overhead? And if it is tolerable in C, why not in C++?
On the other hand, in case it's not because of memory overhead, but because of calling constructors and destructors, couldn't the compiler be smart enough to generate the appropriate code under the hood and let the programmer just write new/delete for both single objects and arrays of objects?
I am writing a compiler for a toy language whose semantics is similar to C++ and it seems that it is possible to let the compiler decides how to allocate and de-allocate only using new/delete, but as C++ uses new/delete and new[]/delete[], maybe there's a catch that I am not seeing right now. Maybe something related to polymorphism and virtual tables?
If you're curious, my naive idea is to simple allocate an integer together with the object/array where this integer is the size of the array or simple 1 in case of being an object. Then, when calling delete, it checks the value of the integer, if it is 1, it calls the destructor. If it greater than 1, then it iterates the array calling the destructor to each object in the array. As I said, it seems to work and would let the programmer just write new/delete instead of new/delete vs new[]/delete. But then again, maybe there's a catch that I am not seeing.
Edited part:
After some answers, I decided to try to provide some pseudo-code and a better background.
In C language, memory allocations are usually made with malloc() and de-allocations with free(). Either if you are allocating a single POD, a single struct or an array, malloc() fits all these cases. There is no need for different versions of malloc() if you are allocating a single struct vs a malloc_array() version if you are allocating an array. At least at the public API level. In other words, it seems it doesn't matter if you are allocating a few bytes or many bytes, there will be no overhead for bookkeeping the allocation size information.
As many of you are aware, including myself, new and delete do more than just allocate and de-allocate memory. New allocate memory and call the constructor and delete calls the destructor and then de-allocate memory. But in C++, you need to be aware if you are allocating just a single object or an array of objects. In case you are allocating an array, you need to use the new[]/delete[] pair.
In C, if you implement a binary tree, nodes will be allocated with malloc and de-allocated with free and in C++ with new and delete. But if you are implementing something like the vector class in C++, in C you still would use malloc/free, but now in C++ you would need to use new[]/delete[] (considering a sane implementation without too much black magic).
Consider the following pseudo-code that is executed by the compiler. In this pseudo-code, the delete function somehow gets access to the malloc internals and knows how many bytes there are, which in turn can be easily used to calculate how many objects there are. As this delete implementation is using malloc internals to know how much memory is allocated, in theory there should be no overhead of bookkeeping.
// ClassType is a meta type only know by the compiler
// it stores a class info such as name, size, constructors and so on
void *new(ClassType c) {
// allocates memory with malloc. Malloc() do the storage bookkeeping
// note that somehow malloc is allocating just a single object
c *ptr = malloc(sizeof(c));
// now, call the constructor of the requested class
c.constructor(ptr);
// return the new object
return ptr;
}
void *new(ClassType c, size_t n) {
c *ptr = malloc(sizeof(c) * n);
// iterate over the array and construct each object
for (i = 0; i < n; ++i) {
c.constructor(ptr[i]);
}
return ptr;
}
// this delete version seems to be able to de-allocate both single
// objects and arrays of objects with no overhead of bookkeeping because
// the bookkeeping is made by malloc/free. So I would need
// just a new/delete pair instead of new/delete vs new[]/delete[]
// Why C++ doesn't use something like my proposed implementation?
// What low-level details prohibits this implementation from working?
void delete(ClassType c, void *ptr) {
// get raw information of how many bytes are used by ptr;
size_t n = malloc_internals_get_size(ptr);
// convert the number of bytes to number of objects in the array
n = c.bytesToClassSize(n);
c* castedPointer = (c*) ptr;
// calls the destructor
for (i = 0; i < n; ++i) {
c.destructor(castedPointer[i]);
}
// free memory chunk
free(ptr);
}
why in C malloc/free can allocate de-allocate both single 'objects'
Malloc doesn't create any objects. It allocates "raw memory" which doesn't contain any objects. Correspondingly, free doesn't destroy any objects. new expressions do create objects, and delete destroys an object, while delete[] destroys an array of objects.
In order for the language implementation to know how many objects need to be destroyed by delete[], that number has to be stored somewhere. In order for the language implementation to know how many objects need to be destroyed by delete, that number does not need to be stored anywhere because it is always one.
Storing a number is not free, and storing an unused number is an unnecessary overhead. The different forms of deletion exist so that the language implementation can destroy the correct number of objects without having to store the number of objects created by a non-array new.
then how malloc/free handles this overhead?
malloc/free doesn't have this overhead since it doesn't create or destroy objects. As such, there is nothing that needs to be handled.
There is an analogous issue of storing the number of allocated bytes that malloc does need to deal with. There is no analogous separate function for allocation or freeing of a single byte. This may be because such use case is probably rare. Malloc has more clever ways of dealing with storing this because allocating more memory than is needed is not observable, while such trick is not possible with number of objects because creation and destruction of objects is observable (at least in case of non-trivial types).
new typically deals with the issue of storing the number of allocated bytes through using malloc internally.
couldn't the compiler be smart enough to generate the appropriate code under the hood
Not without some kind of overhead, no. With overhead yes, it could.
But then again, maybe there's a catch that I am not seeing.
I'm not sure if it is a catch that you haven't seen, but the catch with your idea is the overhead of the integer that is to be allocated even when a single object is allocated.
Some clever implementations of malloc don't actually keep track of the size per allocation (by clever use of rounding up), thus it have extremely low space overhead. They'll allocate a large block of memory, and anytime a dev allocates <64 bytes, it'll just use the next 64 bytes of this block, and mark a single bit elsewhere that tracks that this block of 64 bytes is now in use. Even if the user only wants to allocate 1 byte, it hands out a whole block. This means each allocation has only a single bit overhead, so every 8 allocations has a shared byte of overhead. Practically nothing. (There are far smarter strategies than this, this is just a simplified example)
new and delete can share this super-low-overhead implementation, because delete knows to always destroy one object, regardless of the amount of space it actually has. This is again, super fast, and has low space overhead.
delete[] can't do that because it has to know exactly how many destructors to call. So it has to keep track of how many items are in the array, up to std::size_t, which means ~4 bytes have to be added to every new[]. If the data requires an alignment >4, then each allocation also has to have wasted padding bytes between the count and the first item in the array. And delete[] therefore has to know how to look past the padding, find the count, so it knows exactly how many objects to destroy. This takes both time and more space, for every allocation.
C++ gives you the choice between "always works, but slower and bigger", and "only works for one item, but faster and smaller", so the program can run as fast as possible.
Not all implementations have a difference between new/delete vs new[]/delete[] but they exist because new expression act differently in case of array. thing is that the new expression is not just call to the new operator, underlying operators might be identical:
#include <iostream>
// class-specific allocation functions
struct X {
static void* operator new(std::size_t sz)
{
std::cout << "custom new for size " << sz << '\n';
return ::operator new(sz);
}
static void* operator new[](std::size_t sz)
{
std::cout << "custom new[] for size " << sz << '\n';
return ::operator new(sz);
}
};
int main() {
X* p1 = new X;
delete p1;
X* p2 = new X[10];
delete[] p2;
}
But they maybe overloaded to different ones as well. It might be important difference for native compiler, if you're writing an interpreter or if you don't expect users to modify new\delete, you can do this differently. In C++ new expression call one constructor after allocating memory with provided function, new[] expression would call several and store the count. Of course if compiler got object-oriented memory model, like Java does, then array would be an object with property of size. Single object is just an array of one instance. And as you said, we won't need a separate delete expression.

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()

Can placement new for arrays be used in a portable way?

Is it possible to actually make use of placement new in portable code when using it for arrays?
It appears that the pointer you get back from new[] is not always the same as the address you pass in (5.3.4, note 12 in the standard seems to confirm that this is correct), but I don't see how you can allocate a buffer for the array to go in if this is the case.
The following example shows the problem. Compiled with Visual Studio, this example results in memory corruption:
#include <new>
#include <stdio.h>
class A
{
public:
A() : data(0) {}
virtual ~A() {}
int data;
};
int main()
{
const int NUMELEMENTS=20;
char *pBuffer = new char[NUMELEMENTS*sizeof(A)];
A *pA = new(pBuffer) A[NUMELEMENTS];
// With VC++, pA will be four bytes higher than pBuffer
printf("Buffer address: %x, Array address: %x\n", pBuffer, pA);
// Debug runtime will assert here due to heap corruption
delete[] pBuffer;
return 0;
}
Looking at the memory, the compiler seems to be using the first four bytes of the buffer to store a count of the number of items in it. This means that because the buffer is only sizeof(A)*NUMELEMENTS big, the last element in the array is written into unallocated heap.
So the question is can you find out how much additional overhead your implementation wants in order to use placement new[] safely? Ideally, I need a technique that's portable between different compilers. Note that, at least in VC's case, the overhead seems to differ for different classes. For instance, if I remove the virtual destructor in the example, the address returned from new[] is the same as the address I pass in.
Personally I'd go with the option of not using placement new on the array and instead use placement new on each item in the array individually. For example:
int main(int argc, char* argv[])
{
const int NUMELEMENTS=20;
char *pBuffer = new char[NUMELEMENTS*sizeof(A)];
A *pA = (A*)pBuffer;
for(int i = 0; i < NUMELEMENTS; ++i)
{
pA[i] = new (pA + i) A();
}
printf("Buffer address: %x, Array address: %x\n", pBuffer, pA);
// dont forget to destroy!
for(int i = 0; i < NUMELEMENTS; ++i)
{
pA[i].~A();
}
delete[] pBuffer;
return 0;
}
Regardless of the method you use, make sure you manually destroy each of those items in the array before you delete pBuffer, as you could end up with leaks ;)
Note: I haven't compiled this, but I think it should work (I'm on a machine that doesn't have a C++ compiler installed). It still indicates the point :) Hope it helps in some way!
Edit:
The reason it needs to keep track of the number of elements is so that it can iterate through them when you call delete on the array and make sure the destructors are called on each of the objects. If it doesn't know how many there are it wouldn't be able to do this.
#Derek
5.3.4, section 12 talks about the array allocation overhead and, unless I'm misreading it, it seems to suggest to me that it is valid for the compiler to add it on placement new as well:
This overhead may be applied in all array new-expressions, including those referencing the library function operator new[](std::size_t, void*) and other placement allocation functions. The amount of overhead may vary from one invocation of new to another.
That said, I think VC was the only compiler that gave me trouble with this, out of it, GCC, Codewarrior and ProDG. I'd have to check again to be sure, though.
#James
I'm not even really clear why it needs the additional data, as you wouldn't call delete[] on the array anyway, so I don't entirely see why it needs to know how many items are in it.
After giving this some thought, I agree with you. There is no reason why placement new should need to store the number of elements, because there is no placement delete. Since there's no placement delete, there's no reason for placement new to store the number of elements.
I also tested this with gcc on my Mac, using a class with a destructor. On my system, placement new was not changing the pointer. This makes me wonder if this is a VC++ issue, and whether this might violate the standard (the standard doesn't specifically address this, so far as I can find).
Thanks for the replies. Using placement new for each item in the array was the solution I ended up using when I ran into this (sorry, should have mentioned that in the question). I just felt that there must have been something I was missing about doing it with placement new[]. As it is, it seems like placement new[] is essentially unusable thanks to the standard allowing the compiler to add an additional unspecified overhead to the array. I don't see how you could ever use it safely and portably.
I'm not even really clear why it needs the additional data, as you wouldn't call delete[] on the array anyway, so I don't entirely see why it needs to know how many items are in it.
Placement new itself is portable, but the assumptions you make about what it does with a specified block of memory are not portable. Like what was said before, if you were a compiler and were given a chunk of memory, how would you know how to allocate an array and properly destruct each element if all you had was a pointer? (See the interface of operator delete[].)
Edit:
And there actually is a placement delete, only it is only called when a constructor throws an exception while allocating an array with placement new[].
Whether new[] actually needs to keep track of the number of elements somehow is something that is left up to the standard, which leaves it up to the compiler. Unfortunately, in this case.
Similar to how you would use a single element to calculate the size for one placement-new, use an array of those elements to calculate the size required for an array.
If you require the size for other calculations where the number of elements may not be known you can use sizeof(A[1]) and multiply by your required element count.
e.g
char *pBuffer = new char[ sizeof(A[NUMELEMENTS]) ];
A *pA = (A*)pBuffer;
for(int i = 0; i < NUMELEMENTS; ++i)
{
pA[i] = new (pA + i) A();
}
I think gcc does the same thing as MSVC, but of course this doesn't make it "portable".
I think you can work around the problem when NUMELEMENTS is indeed a compile time constant, like so:
typedef A Arr[NUMELEMENTS];
A* p = new (buffer) Arr;
This should use the scalar placement new.
C++17 (draft N4659) says in [expr.new], paragraph 15:
[O]verhead may be applied in all array new-expressions, including those referencing the library function operator new[](std::size_t, void*) and other placement allocation functions. The amount of overhead may vary from one invocation of new to another.
So it appears to be impossible to use (void*) placement new[] safely in C++17 (and earlier), and it's unclear to me why it's even specified to exist.
In C++20 (draft N4861) this was changed to
[O]verhead may be applied in all array new-expressions, including those referencing a placement allocation function, except when referencing the library function operator new[](std::size_t, void*). The amount of overhead may vary from one invocation of new to another.
So if you're sure that you're using C++20, you can safely use it—but only that one placement form, and only (it appears) if you don't override the standard definition.
Even the C++20 text seems ridiculous, because the only purpose of the extra space is to store array-size metadata, but there is no way to access it when using any custom placement form of new[]. It's in a private format that only delete[] knows how to read—and with custom allocation you can't use delete[], so at best it's just wasted space.
Actually, as far as I can tell, there is no safe way to use custom forms of operator new[] at all. There is no way to call the destructors correctly because the necessary information isn't passed to operator new[]. Even if you know that the objects are trivially destructible, the new expression may return a pointer to some arbitrary location in the middle of the memory block that your operator new[] returned (skipping over the pointless metadata), so you can't wrap an allocation library that only supplies malloc and free equivalents: it also needs a way to search for a block by a pointer to its middle, which even if it exists is likely to be a lot slower.
I don't understand how they (or just Stroustrup?) botched this so badly. The obviously correct way to do it is to pass the number of array elements and the size of each element to operator new[] as two arguments, and let each allocator choose how to store it. Perhaps I'm missing something.