Вопрос

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

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

Спасибо!

Это было полезно?

Решение

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

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

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


Например, в примере распределителя памяти, показанном в 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;

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

Другие советы

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top