views:

317

answers:

4

Looking at some example code and come across some zero-size array allocation. I created the following code snippet to clarify my question

This is valid code:

class T
{
};

int main(void)
{
  T * ptr = new T[0];

  return 0;
}

What is its use? Is ptr valid? Is this construct portable?

A: 

Yes it is valid behaviour, and ptr will be valid. The construct is portable to all C++ compilers that adhere to the C++ Standard. It is useful in that it allows you to write code which doesn't require special-case stuiff to handle the case where the number of elements is zero.

However, as always, you will be better served by using a std::vector (which can also be zero-sized) instead of an array.

anon
+1  A: 

It is authorized (5.3.4/6). Its result is an empty array, so the value returned is the pointer past the array.

AProgrammer
A: 

A related question is: What should malloc(0) return?

And from some C99 docs, the malloc(0) behavior is implementation-defined:

Whether the calloc, malloc, and realloc functions return a null pointer or a pointer to an allocated object when the size requested is zero (7.20.3).

Either a null pointer or a unique pointer that can be passed to free() is returned.

See the malloc(3C) man page.

Granted you're asking about C++, but the malloc info is probably useful anyway.

Mark Rushakoff
C++ new is well defined.
AProgrammer
+6  A: 

5.3.4 in the C++ Standard:

6 Every constant-expression in a direct-new-declarator shall be an integral constant expression (5.19) and evaluate to a strictly positive value. The expression in a direct-new-declarator shall have integral or enumeration type (3.9.1) with a non-negative value...

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.

So, your code allocates an array which behaves in every respect like any other array of T (can be deleted with delete[], passed as a parameter, probably other things). However, it has no accessible indexes (that is, reading or writing ptr[0] results in undefined behaviour).

In this context the different between the constant-expression and the expression is not whether the actual expression is compile time constant (which obviously 0 is), but whether it specifies the "last" dimension of a multi-dimensional array. The syntax is defined in 5.3.4:1.

Steve Jessop