The correct answer here is that it doesn't.
I think what you're talking about (and maybe what the original
poster actually meant to ask) is how the system knows the size
of the memory to be freed. And it's a bit more complicated than
what you suggest---alignment considerations play a role in the
first method, for example, and the size may be implicit, rather
than explicit (the "hidden" data may contain a pointer to the
next block, rather than the actual size). As for the second,
rather than mapping each allocation, the implementation is
likely to maintain separate pools for each size it allocates
(pre-defining a certain number of sizes, and rounding the
request up to the next predetermined size), and use the high
order bits of the address to determine in which pool the memory
resides.
If the size of the array is know by the run-time, what
prevents C++ from exposing this value to the programmer?
It's not. Generally, the system does "know" the size of the
allocated memory, but that's all. And depending on the
allocation algorithm used, this can be considerably larger than
the number of elements times the size of each element.