Помните, что C ++ разделяет выделение памяти и выражение объекта .Выражение new-array-new T * p = new T[N];
выделяет достаточно памяти для N
объектов и для создания этих объектов.С другой стороны, delete[] p;
должен вызвать деструктор всех этих элементов и затем освободить память.
При выделении и освобождении памяти обрабатывается платформой, и свободная память достаточно хорошо идентифицируется для ОСПо одному значению указателя, создание и уничтожение объектов более сложны.Количество реальных объектов должно храниться где-то, и с этой целью стандарт позволяет реализации C ++ запрашивать больше памяти, чем N * sizeof(T)
.Это правда, что указатель p
всегда будет указывать на начало массива N
объектов, но p
не обязательно должен быть тем же указателем, который был возвращен базовым распределителем памяти.(На самом деле, p
гарантированно будет точно значением базового результата выделения, смещенным на избыточный объем памяти.)
Детали полностью оставлены на усмотрение реализации.Некоторые платформы предоставляют дополнительные гарантии;например, Itanium ABI (который называет дополнительные данные "массив cookie") говорит, что память для new T[N]
будет распределена следующим образом:
+- alignof(T) --+-- sizeof(T) --+-- sizeof(T) --+-- sizeof(T) --+-- ...
| ***** [8B: N] | 1st element | 2nd element | 3rd element | .....
+---------------+---------------+---------------+---------------+-- ...
A A
| |_ result of "new T[N]"
|
|_ value returned "operator new[]()"