2013-08-04 2 views
5
int* arr = new int[count]; 

delete arr; 

Почему это работает? Я проверил, и это фактически освобождает память. Из того, что я прочитал, мне нужно delete[] arr;, иначе он фактически не освободит всю память.C++ удалять память массива без скобок все еще работает?

+1

AFAIK это UB. – Borgleader

+3

«Почему это работает?» - это не так, похоже, работает. –

+0

Без скобок вы вызываете только один деструктор, а не все деструкторы в массиве. Также см. Http://stackoverflow.com/questions/2425728/delete-vs-delete-operators-in-c – GreatBigBore

ответ

7

Теперь попробуйте с заполнением массив строк 100 байт каждый, и посмотреть, если он по-прежнему освобождает всю выделенную память ...

Это неопределенное поведение, и, как всегда, иногда UB появится работать. В вашем случае у вас нет деструктора для объектов в памяти, поэтому нет «дальнейшей работы», просто освободите всю память [1]. Но если у вас есть объект, который имеет деструктор, который делает что-то полезное, он (вероятно) не будет вызван.

Вы должны ВСЕГДА использовать delete [], если вы использовали new T[size]; для выделения. Не смешивайте эти два, это всегда неправильно - иногда он ПРОИСХОДИТ работать [так же, как НЕКОТОРЫЕ размеры гаечных ключей в дюймах работают на миллиметровых гайках и наоборот - но по-прежнему неправильно использовать гаечный ключ на метрических гайках].

[1] Обратите внимание, что это может работать для этой конкретной комбинации компилятора/библиотеки C++. Компиляция с другим компилятором, использование другой библиотеки C++ или компиляция для другой ОС может привести к ее сбою при попытке выполнить одно и то же.

3

удалить и удалить [] на самом деле разные операторы, и использовать неправильный всегда есть ошибка. Проблема в том, что в то время это часто кажется прекрасным, но куча повреждена, и вы, скорее всего, испытаете, по-видимому, несвязанный крах позже.

+0

Я не понимаю, почему меня помещают для этого, так как это ИСТИНА. Вы можете попробовать запустить valgrind или аналогичный инструмент анализа памяти, и он покажет кучу, когда это произойдет. –

+1

Я надеюсь, что комментаторы-водовороты. Мне интересно, какая часть может быть неправильной. – user2029077

+0

Я не знаю, почему, это вполне правильный ответ. – Puppy

6

Разница заключается не в том, или не должным образом освобождается выделенная память - используете ли вы

delete 

или

delete[] 

память по-прежнему будет правильно освобождаться.

Разница заключается в том, будут ли надлежащим образом задействованы деструкторы.

delete // will only invoke the destructor of the first element of the array. 

delete[] // will invoke the destructor for *each* element of the array. 

Это не имеет никакого практического эффекта для примитивных типов, таких как Int или плавать, но когда у вас есть массив некоторого класса, разница может иметь решающее значение.

+0

Я могу представить себе реализацию, где это было бы правдой. Есть ли у вас фактическая документация по реализации, которая показывает, что это правда? – sehe

+2

Нет документов, только мой собственный опыт работы с Visual C++. Некоторое время, но я помню ошибки, связанные с ошибками, потому что ошибочно использовал delete вместо delete []. Довольно уверен, что он вел себя так, как я описал ... помните, что * x разыгрывает то же место, что и x [0], и объявляет x как указатель на то, что ничего не говорит о том, является ли целевой объект скалярным или массивом, поэтому оператор удаления не будет знать, что он должен уничтожить массив объекта против скалярного объекта, если вы не скажете его через соответствующую конструкцию удаления. – Zenilogix

Смежные вопросы