как оператор delete работает? Это лучше затем свободное ()?. Также, если Вы делаете ptr=new char[10]
, затем удалите использование delete ptr
, как указатель знает сколько местоположений удалять.
Существует только оператор delete
, free
существует только как функция. В C++ рекомендуется использовать new
/delete
вместо malloc()
/free()
.
В операторе delete есть внутренняя "магия". Когда массив создается с помощью new[]
, размер массива хранится в метаданных блока памяти. delete[]
использует эту информацию.
Все это, конечно, зависит от компилятора, ОС, оптимизатора и реализации.
В C ++ конструктор вызывается с использованием new, но не с использованием malloc. Точно так же деструктор вызывается при использовании delete, но не при использовании free.
Если вы обновили массив с помощью MyClass * x = new MyClass [25], тогда вам нужно вызвать delete [] x, чтобы система знала, что он удаляет (и разрушает) группу объектов вместо единственный.
Вопрос не в том, лучше или хуже. Оба являются операциями с одной и той же целью, выделением и освобождением памяти, но обычно используются в другом контексте 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 ()
.
Добавление к ответу @ Vlad, если вы выделяете память с помощью новой [] формы оператор, например:
char *c = new char[10];
, тогда вы должны использовать соответствующую форму удаления:
delete[] c;
Вы должны явно указать компилятору использовать метаданные во время освобождения.
[EDIT]
Почему нельзя использовать char c []
Поскольку компилятор должен знать размер, который он должен выделить для переменной c в время компиляции. Однако использование формы new [] указывает ему отложить выделение до времени выполнения. Следовательно, ошибка компилятора.
Реализация определяет количество элементов, которые нужно уничтожить (при использовании delete []), за вас. Например:
если вы сделаете тип без массива:
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
имеют дело только с выделением и освобождением памяти.
Конкретно отвечая на ваш вопрос, оператор удаления вызывает деструктор, в отличие от free; следовательно, вы не хотите смешивать malloc / free с new / delete.
Когда библиотека компилятора захватывает память из кучи, она захватывает немного больше, чем вы просите, включая место для ее домашнего хозяйства, некоторые метаданные и, если необходимо, заполнение.
Допустим, вы malloc 128 байт или новый массив из восьми объектов размером по 16 байт. Компилятор может фактически захватить 256 байт, включить небольшой блок управления кучей в начале, записать, что он дал вам 128, но взял 256, и вернуть вам смещение в этот 256-й блок где-то после его заголовка. Вам гарантируется, что из этого указателя у вас будет 128 байтов, которые вы можете использовать, но если вы выйдете за пределы этого указателя, у вас могут возникнуть проблемы.
Операторы free и delete под капотом возьмут переданный вам указатель, сделают резервную копию известного смещения, прочитают его блок заголовка и извлекут 256 байтов обратно в кучу.