Как делает удаление в C++, знают сколько ячеек памяти удалять

как оператор delete работает? Это лучше затем свободное ()?. Также, если Вы делаете ptr=new char[10], затем удалите использование delete ptr, как указатель знает сколько местоположений удалять.

5
задан shreyasva 24 February 2010 в 17:07
поделиться

7 ответов

Существует только оператор delete, free существует только как функция. В C++ рекомендуется использовать new/delete вместо malloc()/free().


В операторе delete есть внутренняя "магия". Когда массив создается с помощью new[], размер массива хранится в метаданных блока памяти. delete[] использует эту информацию.

Все это, конечно, зависит от компилятора, ОС, оптимизатора и реализации.

16
ответ дан 18 December 2019 в 05:28
поделиться
  1. В C ++ конструктор вызывается с использованием new, но не с использованием malloc. Точно так же деструктор вызывается при использовании delete, но не при использовании free.

  2. Если вы обновили массив с помощью MyClass * x = new MyClass [25], тогда вам нужно вызвать delete [] x, чтобы система знала, что он удаляет (и разрушает) группу объектов вместо единственный.

3
ответ дан 18 December 2019 в 05:28
поделиться

Вопрос не в том, лучше или хуже. Оба являются операциями с одной и той же целью, выделением и освобождением памяти, но обычно используются в другом контексте C и C ++. Кроме того, между двумя наборами операций есть некоторые важные различия:

  • new / delete являются ключевыми словами C ++ и недоступны в языке C
  • new / delete безопасны по типу, тогда как malloc () / free () нет. Это означает, что указатели, возвращаемые malloc () и free () , являются указателями void , которые необходимо привести к правильному типу.
  • new / delete неявно поддерживают выделение и удаление массива с использованием синтаксиса new [] и delete [] с использованием метаданных, предоставленных компилятор, malloc () / free () не поддерживают этот синтаксис
  • , применяя new / delete к типу класса T вызовет конструктор и деструктор соответственно T , malloc () / free () не вызывают конструктор и деструктор T
  • malloc () вернет NULL в случае исчерпания памяти, new вызовет исключение

Обратите внимание, что для предотвращения повреждения памяти выделенная память с помощью новый должен быть освобожден с помощью delete .То же самое касается памяти, выделенной с помощью malloc () , которая должна быть освобождена с помощью free () .

3
ответ дан 18 December 2019 в 05:28
поделиться

Добавление к ответу @ Vlad, если вы выделяете память с помощью новой [] формы оператор, например:

char *c = new char[10];

, тогда вы должны использовать соответствующую форму удаления:

delete[] c;

Вы должны явно указать компилятору использовать метаданные во время освобождения.

[EDIT]

Почему нельзя использовать char c []

Поскольку компилятор должен знать размер, который он должен выделить для переменной c в время компиляции. Однако использование формы new [] указывает ему отложить выделение до времени выполнения. Следовательно, ошибка компилятора.

2
ответ дан 18 December 2019 в 05:28
поделиться

Реализация определяет количество элементов, которые нужно уничтожить (при использовании delete []), за вас. Например:

  • new char [10] может выделить несколько дополнительных байтов, поместить количество элементов в начало, а затем вернуть указатель на первый элемент после этого. Затем delete [] может заглянуть за указатель в сохраненный счетчик
  • сохранить эквивалент std :: map , а new T [n] создаст ключ с возвращенным указателем и значение с счет. delete [] найдет указатель на этой карте
  • что-то совершенно другое. Для вас не имеет значения, как это делается, просто то, что это сделано (и, как указывали другие ответы, используйте delete [] с new [] !!)
3
ответ дан 18 December 2019 в 05:28
поделиться

если вы сделаете тип без массива:

T t = new T;
// ...
delete t;

Он будет знать, сколько удалить, потому что он знает, насколько велик T. Если вы создадите массив:

T t* = new T[10];
// ...
delete [] t;

Он установит некоторую дополнительную информацию с выделением, чтобы сообщить ему, сколько удалить. Обратите внимание: мы используем delete [] t с дополнительным [] , чтобы указать, что это массив. Если вы этого не сделаете, он будет думать, что это просто T , и освободит только столько памяти.

Всегда используйте delete , если вы используете new и free , если вы используете malloc . new выполняет две задачи: сначала выделяет память, а затем создает объект. Аналогично delete вызывает деструктор и затем освобождает память. malloc \ free имеют дело только с выделением и освобождением памяти.

5
ответ дан 18 December 2019 в 05:28
поделиться

Конкретно отвечая на ваш вопрос, оператор удаления вызывает деструктор, в отличие от free; следовательно, вы не хотите смешивать malloc / free с new / delete.

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

Допустим, вы malloc 128 байт или новый массив из восьми объектов размером по 16 байт. Компилятор может фактически захватить 256 байт, включить небольшой блок управления кучей в начале, записать, что он дал вам 128, но взял 256, и вернуть вам смещение в этот 256-й блок где-то после его заголовка. Вам гарантируется, что из этого указателя у вас будет 128 байтов, которые вы можете использовать, но если вы выйдете за пределы этого указателя, у вас могут возникнуть проблемы.

Операторы free и delete под капотом возьмут переданный вам указатель, сделают резервную копию известного смещения, прочитают его блок заголовка и извлекут 256 байтов обратно в кучу.

3
ответ дан 18 December 2019 в 05:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: