Can C++ array end at memory boundary? Can C++ array end at memory boundary? arrays arrays

Can C++ array end at memory boundary?


An implementation must allow a pointer to one past the end toexist. How it does this is its business. On many machines, youcan safely put any value into a pointer, without risk (unlessyou dereference it); on such systems, the one past the endpointer may point to unmapped memory—I'veactually encountered a case under Windows where it did.

On other machines, just loading a pointer to unmapped memoryinto a register will trap, causing the program to crash. Onsuch machines, the implementation must ensure that this doesn'thappen, either by refusing to use the last byte or word ofallocated memory, or by ensuring that all use of the pointerother than dereferencing it avoids any instructions which mightcause the hardware to treat it as an invalid pointer. (Most suchsystems have separate address and data registers, and will onlytrap if the pointer is loaded into an address register. If thedata registers are large enough, the compiler can safely loadthe pointer into a data register for e.g. comparison. This isoften necessary anyway, as the address registers don't alwayssupport comparison.)

Re your last question: C and C++ are exactly identical in this respect; C++ simply took over the rules from C.


There's an interesting passage at §3.9.2/3 [Compound types]:

The type of a pointer to void or a pointer to an object type is called an object pointer type. [...] A valid value of an object pointer type represents either the address of a byte in memory (1.7) or a null pointer (4.10).

Together with the text at §5.7/5 [Additive operators]:

[...] Moreover, if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object, and if the expression Q points one past the last element of an array object, the expression (Q)-1 points to the last element of the array object.

it seems that an array ending at the last byte in memory can not be allocated, if there is a requirement that the one-past-the-end pointer must be valid. If the one-past-the-end pointer is allowed to be invalid, I don't know the answer.

The section §3.7.4.2/4 [Deallocation functions] states that:

The effect of using an invalid pointer value (including passing it to a deallocation function) is undefined.

Thus if comparing a one-past-the-end pointer for an allocated array must be supported, the one-past-the-end pointer must be valid.

Based on the comments I got, I assume that an implementation can allocate an array without having to care about if the array's one-past-the-end pointer is usable or not. However I would like to find out the relevant passages in the standard for this.


You're half right. Suppose a hypothetical implementation uses linearly addressed memory and pointers that are represented as 16-bit unsigned integers. Suppose also that the null pointer is represented as zero. And finally, suppose you ask to for 16 bytes of memory, with char *p = malloc(16);. Then it's guaranteed that you will get a pointer of which the numeric value is less than 65520. The value 65520 itself wouldn't be valid, because as you rightly point out, assuming the allocation succeeded, p + 16 is a valid pointer that must not be a null pointer.

However, suppose now that a hypothetical implementation uses linearly addressed memory and pointers that are represented as 32-bit unsigned integers, but only has an address space of 16 bits. Suppose also again that the null pointer is represented as zero. And finally, suppose again that you ask for 16 bytes of memory, with char *p = malloc(16);. Then it's only guaranteed that you will get a pointer of which the numeric value is less than or equal to 65520. The value 65520 itself would be valid, so long as the implementation makes sure that adding 16 to that gives you the value 65536, and that subtracting 16 gets you back to 65520. This is valid even if no memory (physical or virtual) exists at all at address 65536.