В типичной реализации размер динамического блока памяти как-то сохраняется в самом блоке - это правда. Но нет стандартного способа доступа к этой информации. (Реализации могут предоставлять специфические для реализации способы доступа к нему). Вот как у malloc/free
, вот как у new[]/delete[]
.
Фактически, в типичной реализации необработанные выделения памяти для вызовов new[]/delete[]
в конечном итоге обрабатываются некоторой парой malloc/free
-подобной реализации, что означает, что delete[]
на самом деле не нужно заботиться о том, сколько памяти для освобождения: он просто вызывает этот внутренний free
(или как его там называют), который позаботится об этом.
Что нужно знать delete[]
, так это то, сколько элементов разрушает в ситуациях, когда тип элемента массива имеет нетривиальный деструктор. И вот о чем ваш вопрос - количество элементов массива , а не размер блока (эти два значения не совпадают, блок может быть больше, чем на самом деле требуется для самого массива). По этой причине количество элементов в массиве обычно также сохраняется внутри блока с помощью new[]
, а затем извлекается с помощью delete[]
для правильного уничтожения элементов массива. Также нет стандартных способов доступа к этому номеру.
(Это означает, что в общем случае типичный блок памяти, выделенный new[]
, будет независимо хранить одновременно и размер физического блока в байтах и количество элементов массива. Эти значения сохраняются различными уровнями механизма выделения памяти C ++ - необработанным распределителем памяти и самим new[]
соответственно - и никак не взаимодействуют друг с другом).
Однако обратите внимание, что по указанным выше причинам количество элементов массива обычно сохраняется только тогда, когда тип элемента массива имеет нетривиальный деструктор. То есть этот счет не всегда присутствует. Это одна из причин, по которой предоставление стандартного способа доступа к этим данным неосуществимо: вам придется либо хранить их всегда (что тратит память), либо ограничивать их доступность типом деструктора (что сбивает с толку).
Чтобы проиллюстрировать вышеизложенное, при создании массива int
s
int *array = new int[100];
размер массива (т. Е. 100
) равен , а не , обычно хранится new[]
, поскольку delete[]
не заботится об этом (int
не имеет деструктора). Физический размер блока в байтах (например, 400 байтов или более) обычно сохраняется в блоке необработанным распределителем памяти (и используется обработчиком необработанной памяти, вызываемым delete[]
), но может легко оказаться равным 420 по какой-то конкретной причине реализации. Таким образом, этот размер в принципе бесполезен для вас, так как вы не сможете получить точный исходный размер массива из него.