размер динамично выделенного массива

Действительно ли это верно, что указатель, присвоенный начальному адресу динамично выделенного массива, не имеет информации размера массива? Таким образом, мы должны использовать другую переменную для хранения ее размера для дальнейшей обработки массив через указатель.

Но когда мы освобождаем динамично выделенный массив, мы не определяем размер, вместо этого мы просто "свободный ptr" или "удаляем [] ptr". Как мог освободить или удалить, знают размер массива? Мы можем использовать тот же план постараться не хранить размер массива в другой переменной?

Спасибо!

15
задан Jonathan Leffler 9 January 2010 в 18:52
поделиться

4 ответа

Да, это правда.

Удалить знает размер куска памяти, потому что новый добавляет дополнительную информацию в кусок (обычно до того, как область возвращается пользователю), содержащая его размер вместе с другой информацией. Обратите внимание, что это все очень особенное реализация, и не следует использовать вашим кодом.

Итак, чтобы ответить на ваш последний вопрос: NO - мы не можем его использовать - это деталь реализации, которая зависит от платформы и компилятора.


Например, в выборочном распределении памяти, продемонстрированный в K & R2, это «заголовок», расположенный перед каждым выделенным кусочком:

typedef long Align; /* for alignment to long boundary */

union header { /* block header */
  struct {
    union header *ptr; /* next block if on free list */
    unsigned size; /* size of this block */
  } s;

  Align x; /* force alignment of blocks */
};

typedef union header Header;

размер - это размер выделенного блока (который затем используется , или Удалить ).

18
ответ дан 1 December 2019 в 02:10
поделиться

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

3
ответ дан 1 December 2019 в 02:10
поделиться

Забавно, что исторически это было delete [20] arr; так же как это было arr = new int[20] . Однако практика показала, что информация о размере может безболезненно храниться аллокатором, а так как большинство людей, использующих его, все равно его сохраняли, то он был добавлен в стандарт.

Более забавным и малоизвестным является тот факт, что этот "расширенный синтаксис delete" на самом деле поддерживается несколькими компиляторами C++ (несмотря на то, что он некорректен даже перед лицом стандарта C++98), хотя ни один из них этого не требует.

int* arr = new int[20];
delete [20] arr;

Однако печальная часть всего этого заключается в том, что не существует стандартного способа извлечения переданного размера для собственного использования :-/

.
7
ответ дан 1 December 2019 в 02:10
поделиться

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

2
ответ дан 1 December 2019 в 02:10
поделиться