2010-03-11 4 views
70

В чем разница между операторами и delete[] на C++?delete vs delete [] операторов в C++

+0

Возможно, этот вопрос релевантен http://stackoverflow.com/questions/1913343/how-could-pairing-new-with-delete-possible-lead-to-memory-leak-only – sharptooth

+4

Проблемы с удалением и delete [] - одна из причин, по которой мне нравятся интеллектуальные указатели, и используя 'vector <>' вместо массива всякий раз, когда я могу. –

+0

http://stackoverflow.com/questions/1553382/pod-freeing-memory-is-delete-equal-to-delete – sbi

ответ

88

Оператор delete освобождает память и вызывает деструктор для одного объекта, созданного с помощью new.

Оператор delete [] освобождает память и вызывает деструкторы для массива объектов, созданных с помощью new [].

delete Использование на указатель, возвращаемый new [] или delete [] на указатель, возвращаемый new приводит к неопределенному поведению.

+1

Интересно, если использовать delete в новом [] массиве примитивных типов, таких как int или char (без конструктора/destructor) обязательно приводит к неопределенному поведению.Кажется, размер массива не хранится нигде при использовании примитивных типов. – thomiel

+12

Если стандарт не определяет, что произойдет, когда это будет сделано, это по определению «неопределенное поведение», даже если ваш компилятор детерминированно делает то, что вы хотели бы сделать. Другой компилятор может сделать что-то совершенно другое. –

+0

Я сделал эту ошибку, когда у меня был массив строк C, например «char ** strArray». Если у вас есть такой массив, как я, вам нужно перебирать массив и удалять/освобождать каждый элемент, а затем удалять/освобождать сам strArray. Использование «delete []» в массиве, с которого у меня не работает (как указано в приведенных выше комментариях и ответах), IT CALLS DESTRUCTORS, фактически не освобождает каждый слот. – Katianie

4

delete Операторы и delete [] используются соответственно для уничтожения объектов, созданных с new и new[], возвращаясь к выделенной памяти остается доступным для менеджера памяти компилятора.

Объекты, созданные с помощью new, обязательно должны быть уничтожены с помощью delete и что массивы, созданные с помощью new[], должны быть удалены с помощью delete[].

75

Оператор delete[] используется для удаления массивов. Оператор delete используется для удаления объектов без массива. Он вызывает функции operator delete[] и operator delete, соответственно, для удаления памяти, занятой массивом или объектом без массива после (в конечном счете) вызова деструкторов для элементов массива или объекта без массива.

Ниже приведены соотношения:

typedef int array_type[1]; 

// create and destroy a int[1] 
array_type *a = new array_type; 
delete [] a; 

// create and destroy an int 
int *b = new int; 
delete b; 

// create and destroy an int[1] 
int *c = new int[1]; 
delete[] c; 

// create and destroy an int[1][2] 
int (*d)[2] = new int[1][2]; 
delete [] d; 

Для более new, который создает массив (так, либо new type[] или new применяется к типу массива конструкции), стандарт выглядит для operator new[] в элементе массива типа или в глобальной области и передает объем запрошенной памяти. Он может запросить более N * sizeof(ElementType), если он захочет (например, для хранения количества элементов, поэтому позже, когда удаление знает, сколько вызовов деструкторов сделано). Если класс объявляет operator new[], что дополнительный объем памяти принимает другой size_t, этот второй параметр получит количество выделенных элементов - он может использовать его для любых целей, которые он хочет (отладка и т. Д.).

Для new, который создает объект без массива, он будет искать operator new в классе элемента или в глобальной области. Он передает объем запрошенной памяти (ровно sizeof(T)).

Для delete[] он просматривает тип класса элементов массивов и вызывает их деструкторы. Используемая функция operator delete[] является той, которая находится в классе элемента, или если в глобальной области нет ни одного.

Для delete, если переданный указатель является базовым классом типа фактического объекта, базовый класс должен иметь виртуальный деструктор (в противном случае поведение не определено). Если это не базовый класс, то деструктор этого класса вызывается и используется operator delete в этом классе или глобальном operator delete. Если базовый класс был передан, тогда вызывается деструктор фактического типа объекта, и используется operator delete, найденный в этом классе, или если его нет, вызывается глобальный operator delete.Если у operator delete в классе есть второй параметр типа size_t, он получит количество элементов для освобождения.

8

Это основное использование выделить/DE-выделить шаблон в C++ таНос/бесплатно, новые/удалить, новый []/удалить []

Мы должны использовать их соответственно. Но я хотел бы добавить это особое понимание разницы между удалением и удалением []

1) удалить используются для снятия выделения памяти, выделенная для одного объекта

2) удалить [] используется для снятия выделения памяти, выделенной для массива объектов

класса ABC {}

ABC * PTR = новый ABC [100]

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

, но, соответственно, если мы просто используем удалить PTR для этого случая, компилятор не будет знать, как много объектов, PTR указывает на и в конечном итоге вызова деструктора и удаления памяти только 1 объект (оставление вызова деструкторов и освобождение оставшихся 99 объектов). Следовательно, будет утечка памяти

поэтому нам нужно использовать delete [] ptr в этом случае.

+2

Это должен быть правильный ответ. Ни один из других ответов не говорит о различии: «но, соответственно, если мы просто используем delete ptr для этого случая, компилятор не будет знать, сколько объектов, на которые указывает ptr, и в конечном итоге вызовет деструктор и удалит память только для одного объекта» –

+0

Как мы достигаем того же самого в C? –

-1

delete Используется для одного указателя, а delete[] используется для удаления массива с помощью указателя. This может помочь вам лучше понять.

0

Когда я задал этот вопрос, мой реальный вопрос: «Есть ли разница между этими двумя? Не должна ли среда выполнения хранить информацию о размере массива, и так не сможет ли она сказать, какой из них мы имею в виду?" Этот вопрос не встречается в «связанных вопросах», поэтому просто для того, чтобы помочь тем, кто мне нравится, вот ответ на этот вопрос: "why do we even need the delete[] operator?"

0

Ну .. может, я думаю, что это просто для явного. Оператор delete и operator delete [] отличается, но оператор delete также может освобождать массив.

test* a = new test[100]; 
delete a; 

И уже проверено, что этот код не имеет утечки памяти.