Consider
int main()
{
auto a = new int[0];
delete[] a; // So there's no memory leak
}
Between the copy initialisation and deletion, are you allowed to read the pointer at a + 1
?
Furthermore, does the language permit the compiler to set a
to nullptr
?
Zero-length arrays, also known as flexible arrays, are used to implement variable-length arrays, primarily in structures. That's a little confusing, so let's look at an example. Say you wanted a structure to represent an email: Yes, we're missing a lot of fields. This is just an example; bear with me.
The pointer ptr, and all pointers, are 8 bytes, because they hold addresses, which are 8 bytes, or 64 bits. Assigning any address to an array variable is not allowed.
Although the size of a zero-length array is zero, an array member of this kind may increase the size of the enclosing type as a result of tail padding. The offset of a zero-length array member from the beginning of the enclosing structure is the same as the offset of an array with one or more elements of the same type.
Per recent CWG reflector discussion as a result of editorial issue 3178, new int[0]
produces what is currently called a "past-the-end" pointer value.
It follows that a
cannot be null, and a + 1
is undefined by [expr.add]/4.
auto a = new int[0];
According to [basic.compound.3], the value stored in a
must be one of the following:
int
)We can rule out the first possibility since there were no objects of type int
constructed. The third possibility is ruled out since C++ requires a non-null pointer to be returned (see [basic.stc.dynamic.allocation.2]). Thus we are left with two possibilities: a pointer past the end of an object or an invalid pointer.
I would be inclined to view a
as a past-the-end pointer, but I don't have a reputable reference to definitively establish that. (There is, though, a strong implication of this in [basic.stc], seeing how you can delete
this pointer.) So I'll entertain both possibilities in this answer.
Between the copy initialisation and deletion, are you allowed to read the pointer at
a + 1
?
The behavior is undefined, as dictated by [expr.add.4], regardless of which possibility from above applies.
If a
is a past-the-end pointer, then it is considered to point to the hypothetical element at index 0
of an array with no elements. Adding the integer j
to a
is defined only when 0≤0+j≤n
, where n
is the size of the array. In our case, n
is zero, so the sum a+j
is defined only when j
is 0
. In particular, adding 1
is undefined.
If a
is invalid, then we cleanly fall into "Otherwise, the behavior is undefined." (Not surprisingly, the cases that are defined cover only valid pointer values.)
Furthermore, does the language permit the compiler to set
a
tonullptr
?
No. From the above-mentioned [basic.stc.dynamic.allocation.2]: "If the request succeeds, the value returned by a replaceable allocation function is a non-null pointer value". There is also a footnote calling out that C++ (but not C) requires a non-null pointer in response to a zero request.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With