Question

I always thought T *p = new T; was valid C++ for all T... until I tried

int main()
{
    typedef int Array[2];
    Array *p = new Array;
}

and got this cute error I couldn't decipher:

error C2440: 'initializing' : cannot convert from 'int *' to 'Array (*)'

Could someone please explain why this is an error?

Was it helpful?

Solution

If you dynamically allocate an array type, you get a pointer to its first element.

§5.3.4 [expr.new] Entities created by a new-expression have dynamic storage duration. If the entity is a non- array object, [...]. If it is an array, the new-expression returns a pointer to the initial element of the array.

So since you're allocating an array type object, you get an int* out of it:

int *p = new Array;

This is no different to not using the typedef:

int *p = new int[2];

This also doesn't match your T *p = new T; rule. That is, you definitely can't do this:

int (*p)[2] = new int[2];

I realise this confusion may have been caused by thinking of new ...[] as a special type of expression different to new ..., where new Array fits into the latter case. We often suggest it might be by saying things like "new[] should always match with delete[]". Well that rule is a little misleading. What is really meant here is that new with an array type should always be matched with delete[].

OTHER TIPS

The problem here is that array type syntax in C and C++ is a jumbled mess, and typedefing an array type to something that doesn't look so jumbled doesn't make it any less so.

The result, in an expression, of dynamically allocating an array is a pointer, not an array. The types are different.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top