Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In cpp what is the difference between `new int` and `new int[1]`?

I am currently learning C++ and am struggling to understand what the difference is between the following two lines of code:

int* a = new int;
int* b = new int[1];

As far as I understand, both statements return an int pointer and only allocate space for 1 int on the heap. So, is there any practical difference between them, or are they just synonyms?

like image 350
gowerc Avatar asked Nov 07 '25 21:11

gowerc


1 Answers

As noted in the other answers, the rules are the rules and if you want to write valid C++ that is guaranteed to work, even with future compilers, you must follow them.

However, in this case and most other cases where rules may seem arbitrary at first, there is a good reason for it:

The expression new int[N], where N can be a value only known at runtime, yields a pointer to an array of ints. To deallocate it, you write delete[] p, where p is the result of the new int[N] expression. Note that you need to specify the array size to allocate, but not to deallocate. Most common allocators which are used to implement new and delete however will need to know the size of the allocated memory region to deallocate it. So what many compilers do, is allocate more memory than is necessary to store the array, take a little chunk in the beginning of the allocated memory region and store the size of the array in there. Then the pointer will be incremented to just past the region where the size is stored and returned to you. When you deallocate the array, the program will decrement the pointer, read the array size and pass the proper size of the memory region to the underlying allocators deallocation function.

Note that this is an implementation detail. You must not rely on the size being stored before the array. Some compilers might implement array allocation differently, but this is a common method. The C++ standard only specifies, that you must always match new with delete and new[N] with delete[]. Then the compiler is free to do with that whatever it wants or deems most efficient.

I should also note that the C++ committee could have decided to require you to explicitly pass the size of the array to delete[] like so:

delete [N] p;

But they haven't, perhaps because it may seem simpler to free the programmer from having to store the size themselves. I personally disagree with this decision but things are the way they are.

This is why, in practice on most compilers, new int and new int[1] will allocate differently sized memory regions and the result of new int[1] won't even point to the beginning of a memory region that was allocated by the underlying allocator. So when you try to deallocate your b pointer with delete b the allocator would get very confused because it would be given the pointer b to deallocate which has never been handed out before.


Also the mandatory note: Always prefer std::vector<T> to new T[N] and std::make_unique<T>(...) to new T(...) unless you have a very good reason to choose the latter.

like image 98
chrysante Avatar answered Nov 09 '25 12:11

chrysante