Подтвердить что ты не робот

Почему невозможно получить доступ к размеру нового массива [] 'd?

Когда вы выделяете массив с помощью new [], почему вы не можете узнать размер этого массива из указателя? Он должен быть известен во время выполнения, иначе delete [] не знает, сколько свободного места памяти.

Если мне что-то не хватает?

4b9b3361

Ответ 1

В типичной реализации размер динамического блока памяти каким-то образом сохраняется в самом блоке - это правда. Но нет стандартного способа доступа к этой информации. (Реализации могут предоставить конкретные способы реализации для доступа к нему). Так оно и есть с malloc/free, так оно и есть с new[]/delete[].

Фактически, в типичной реализации необработанные выделения памяти для вызовов new[]/delete[] в конечном итоге обрабатываются некоторой специфичной для реализации парой malloc/free, что означает, что delete[] действительно не нужно заботиться о том, сколько памяти для освобождения: он просто вызывает это внутреннее free (или то, что он назван), что позаботится об этом.

То, что delete[] действительно нужно знать, - это то, сколько элементов нужно разрушать в ситуациях, когда тип элемента массива имеет нетривиальный деструктор. И в этом ваш вопрос - количество элементов массива, а не размер блока (эти два не совпадают, блок может быть больше, чем требуется для самого массива). По этой причине количество элементов в массиве обычно также сохраняется внутри блока с помощью new[] и затем извлекается delete[] для выполнения правильного уничтожения элемента массива. Нет стандартных способов доступа к этому номеру.

(Это означает, что в общем случае типичный блок памяти, выделенный new[], будет независимо, одновременно хранить как размер физического блока в байтах, так и количество элементов массива. Эти значения хранятся на разных уровнях механизма распределения памяти С++ - raw memory allocator и new[] соответственно - и не взаимодействуют друг с другом каким-либо образом).

Однако обратите внимание, что по вышеуказанным причинам подсчет элемента массива обычно сохраняется только тогда, когда тип элемента массива имеет нетривиальный деструктор. То есть этот счет не всегда присутствует. Это одна из причин, по которой предоставление стандартного способа доступа к этим данным не представляется возможным: вам нужно либо хранить его всегда (что отнимает память), либо ограничивать его доступность по типу деструктора (что запутывает).

Чтобы проиллюстрировать это, при создании массива int s

int *array = new int[100];

размер массива (т.е. 100) обычно не сохраняется new[], так как delete[] не заботится об этом (int не имеет деструктора). Физический размер блока в байтах (например, 400 байт или более) обычно сохраняется в блоке с помощью распределителя необработанной памяти (и используется средством освобождения памяти, вызванным delete[]), но он может легко оказаться 420 по какой-то конкретной причине. Таким образом, этот размер в основном бесполезен для вас, так как вы не сможете получить из него точный размер оригинального массива.

Ответ 2

Вы, скорее всего, сможете получить к нему доступ, но для этого вам потребуется интимное знание вашего распределителя и не будет переносимым. В стандарте С++ не указывается, как реализации хранят эти данные, поэтому нет согласованного метода его получения. Я считаю, что это оставлено неуказанным, потому что разные распределители могут захотеть сохранить его разными способами для повышения эффективности.

Ответ 3

Это имеет смысл, так как, например, размер выделенного блока может не быть того же размера, что и массив. В то время как верно, что new[] может хранить количество элементов (вызов каждого деструктора элементов), это не так, как было бы для пустого деструктора. Также нет стандартного способа (С++ FAQ Lite 1, С++ FAQ Lite 2), где new[] хранит длину массива, поскольку каждый метод имеет свои плюсы и минусы.

Другими словами, он позволяет распределять как можно дешевле, не указывая ничего о реализации. (Если реализация должна хранить размер массива, а также размер выделенного блока каждый раз, он отнимает память, которая вам может не понадобиться).

Ответ 4

Проще говоря, стандарт С++ не требует поддержки для этого. Возможно, что, если вы знаете достаточно о внутренних компонентах своего компилятора, вы можете выяснить, как получить доступ к этой информации, но это обычно считается плохой практикой. Обратите внимание, что может быть разница в структуре памяти для массивов, распределенных по кучам, и массивов, распределенных по стекам.

Помните, что в основном вы говорите здесь о массивах C-стиля, даже если new и delete являются операторами С++, и поведение наследуется от C. Если вам нужен массив С++ ", который имеет размер, вы должны использовать STL (например, std::vector, std:: deque).