Я видел пример использования функции delete в cpp и не совсем понял его. код такой:
class Name {
const char* s;
//...
};
class Table {
Name* p;
size_t sz;
public:
Table(size_t s = 15){p = new Name[sz = s]; }
~Table { delete[] p; }
};
Что такое точное действие команды: delete [] p;
?
Я думаю, что целью было удалить все указатели в таблице контейнера.
Скобки в delete []
дают мне понять, что он удаляет массив указателей на Name, но размер массива не указан, поэтому как деструктор «знает», сколько указателей на удалить?
delete
не функция, это оператор.
Выражение delete
с использованием []
уничтожает объекты, созданные с помощью new ... []
, и освобождает связанную память. delete []
должен использоваться для указателей, возвращаемых new ... []
; без массива удалить
только для указателей, возвращаемых не-массивом new
. Использование несоответствующей формы удаления
всегда неверно.
Выражение delete
в ~ Table ()
(отсутствует ()
в вашем коде) уничтожит динамически созданный массив Name
объекты, гарантирующие, что деструктор Name
вызывается для каждого члена массива.
Это реализация для реализации некоторого механизма записи количества элементов в массивах, выделенных с помощью new ... []
, программисту не нужно об этом беспокоиться.
Во многих реализациях, где элементы массива имеют нетривиальные деструкторы, выражение new []
выделяет дополнительное пространство для записи количества элементов перед пространством для всех элементов массива. Этот скрытый счетчик затем просматривается, когда используется delete []
, чтобы гарантировать правильное количество вызываемых деструкторов.Это всего лишь деталь реализации, хотя возможны и другие реализации.
Короче говоря, delete []
знает размер удаляемого массива, потому что это необходимо.
Потому что в стандарте языка C ++ сказано, что он должен знать.
Таким образом, когда вы выделяете массив, система должна хранить его где-нибудь там, где delete []
может его найти.
Один из вариантов - выделить на несколько байтов больше, чем необходимо. Используйте первые байты, чтобы указать размер, а затем вместо возврата указателя на первый выделенный байт верните указатель на первый байт после поля размера.
Затем delete []
просто нужно вычесть несколько байтов из указателя, чтобы определить размер.
Другой вариант - иметь глобальную карту
, где ключ является указателем на выделение памяти, а значение - это размер этого выделения. Есть много других способов, которыми delete []
может узнать размер. Стандарт C ++ не указывает, какой из них использовать. Он просто говорит, что delete []
должен знать размер, и оставляет его разработчикам решать , как это реализовать.