views:

2552

answers:

4

A simple test app:

cout << new int[0] << endl;

outputs:

0x876c0b8

So it looks like it works. What does the standard say about this? Is it always legal to "allocate" empty block of memory?

+6  A: 

Yes, it is legal to allocate a zero-sized array like this. But you must also delete it.

anon
Do you have a citation for this? We all know that `int ar[0];` is illegal why is new OK?
Motti
See Faisal's answer.
anon
It's interesting that C++ isn't so strong with forbidding zero sized objects. Think of the empty base class optimization: Here too, an empty base class sub-object may have size zero. In contrast, the C Standard makes a strong effort to ensure there never are zero sized objects created: In defining malloc(0) it says the effect is of running malloc with some non-zero argument, for example. And in struct { ...; T n[]; }; when there is no space allocated for the array (FAM), it says it behaves as if "n" has one element. (In both cases, using the object in any way is UB, like x.n[0])
Johannes Schaub - litb
+34  A: 

From 5.3.4/7

When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements.

From 3.7.3.1/2

The effect of dereferencing a pointer returned as a request for zero size is undefined.

Also

Even if the size of the space requested [by new] is zero, the request can fail.

That means you can do it, but you can not legally (in a well defined manner across all platforms) dereference the memory that you get - you can only pass it to array delete - and you should delete it.

Here is an interesting foot-note (i.e not a normative part of the standard, but included for expository puprposes) attached to the sentence from 3.7.3.1/2

[32. The intent is to have operator new() implementable by calling malloc() or calloc(), so the rules are substantially the same. C++ differs from C in requiring a zero request to return a non-null pointer.]

Faisal Vali
+4  A: 

Yes it is completely legal to allocate a 0 sized block with new. You simply can't do anything useful with it since there is no valid data for you to access. int[0] = 5; is illegal.

However, I believe that the standard allows for things like malloc(0) to return NULL.

You will still need to delete [] whatever pointer you get back from the allocation as well.

Evan Teran
Regarding malloc, you are right - it is implementation defined. This is often seen as a misfeature.
anon
I suppose an interesting question is: can the nothrow version of new return NULL if given a size of 0?
Evan Teran
The semantics of new and malloc are not linked in any way, at least by the standard.
anon
not saying they are... was specifically asking about the nothrow version of new.
Evan Teran
@Evan - the nothrow version of new returns null only if the request fails - not just if the request size is 0 @Neil - not normatively linked - but linked by intent (i.e. operator new may be implemented in terms of malloc but not the other way around) - see the footnote i included in my answer
Faisal Vali
+6  A: 

What does the standard say about this? Is it always legal to "allocate" empty block of memory?

Every object has a unique identity, i.e. a unique address, which implies a non-zero length (the actual amount of memory will be silently increased, if you ask for zero bytes).

If you allocated more than one of these objects then you'd find they have different addresses.

ChrisW