Как удалить [] "знать" размер массива операндов?

Foo* set = new Foo[100];
// ...
delete [] set;

Вы не передаете границы массива в delete[]. Но где хранится эта информация? Стандартизировано ли оно?

Ответ 1

Когда вы выделяете память в куче, ваш распределитель будет отслеживать, сколько памяти вы выделили. Обычно это хранится в сегменте "голова" непосредственно перед памятью, которую вы получаете. Таким образом, когда он освобождает память, де-распределитель точно знает, сколько памяти освободится.

Ответ 2

ОДИН из подходов для компиляторов заключается в том, чтобы выделить немного больше памяти и сохранить количество элементов в элементе head.

Пример того, как это можно сделать:

Здесь

int* i = new int[4];

компилятор выделяет sizeof(int)*5 байты.

int *temp = malloc(sizeof(int)*5)

Будет хранить "4" в первом sizeof(int) байтах

*temp = 4;

и установите i

i = temp + 1;

Итак, i будет указывать на массив из 4 элементов, а не на 5.

И удаление

delete[] i;

будет обрабатываться следующим образом:

int *temp = i - 1;
int numbers_of_element = *temp; // = 4
... call destructor for numbers_of_element elements
... that are stored in temp + 1, temp + 2, ... temp + 4 if needed
free (temp)

Ответ 3

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

Также вы должны использовать delete [], когда вы выделили память с помощью нового [], так как версия версии delete знает, что (и где) нужно искать, чтобы освободить нужный объем памяти - и вызвать соответствующий количество деструкторов для объектов.

Ответ 4

В основном его расположение в памяти:

[info] [mem вы просили...]

Где информация - это структура, используемая вашим компилятором для хранения объема выделенной памяти, а что нет.

Это зависит от реализации.

Ответ 5

Это не то, что зависит от зависимостей спецификации.

Ответ 6

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

Вы можете думать о возможных реализациях, понимая, что delete[] определяется только для указателей, возвращаемых new[], которые могут не совпадать с указателем, возвращаемым operator new[]. Одна из реализаций в дикой природе состоит в том, чтобы сохранить количество массивов в первом int, возвращаемом operator new[], и new[] вернуть обратно смещение указателя. (Вот почему нетривиальные выравнивания могут сломаться new[].)

Имейте в виду, что operator new[]/operator delete[]!= new[]/delete[].

Плюс, это ортогонально тому, как C знает размер памяти, выделенный malloc.

Ответ 7

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

Ответ 8

Это не стандартизировано. В среде выполнения Microsoft новый оператор использует malloc(), а оператор delete использует free(). Итак, в этой настройке ваш вопрос эквивалентен следующему: как free() знает размер блока?

Существует некоторая бухгалтерия, идущая за кулисами, т.е. во время выполнения C.

Ответ 9

Это более интересная проблема, чем вы могли бы подумать вначале. Этот ответ касается одной возможной реализации.

Во-первых, хотя на каком-то уровне ваша система должна знать, как "освобождать" блок памяти, базовый malloc/free (который обычно вызывает /new/delete/new []/delete []) не всегда помнит точно сколько памяти вы просите, его можно округлить (например, если вы выше 4K, он часто округляется до следующего блока размером 4 КБ).

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

ЗА ИСКЛЮЧЕНИЕМ, если построенный тип не имеет деструктора, тогда delete [] не должен ничего делать, кроме освобождения блока памяти, и поэтому ему не нужно ничего хранить!