Как удалить [] "знать" размер массива операндов?
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 [] не должен ничего делать, кроме освобождения блока памяти, и поэтому ему не нужно ничего хранить!