Должно ли возникнуть предупреждение или, возможно, даже отказ от утверждения, если удаление используется для освобождения памяти, полученной с помощью malloc()?

В С++ с использованием delete для освобождения памяти, полученной с помощью malloc(), не обязательно приводит к взрыву программы.

Должно ли возникнуть предупреждение или, возможно, даже отказ от утверждения, если delete используется для освобождения памяти, полученной с помощью malloc()?

Почему у Stroustrup нет этой функции на С++?

Ответы

Ответ 1

В С++ использование удаления в свободную память, полученное с помощью malloc(), не обязательно приводит к взрыву программы.

Нет, но это обязательно приводит к поведению undefined, что означает, что что-то может случиться, включая взлом программы или программу, продолжающую работать в том, что кажется правильным.

Вы, ребята, думаете, что предупреждение или, возможно, даже отказ от утверждения должны быть получены, если удаление используется для освобождения памяти, полученной с помощью malloc()??

Нет. Это сложно, если не невозможно, проверить во время компиляции. Проверки времени выполнения дороги, и на С++ вы не получаете то, за что не платите.

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

Ответ 2

delete имеет специальное свойство, которое free() не выполняет: оно вызывает деструкторы, которые, в свою очередь, могут вызывать больше удалений, поскольку этот объект может выделить другие вещи в куче.

Тем не менее, new также вызывает конструктор объекта, а malloc() - нет. Не смешивайте эти вещи, если вы не уверены, что знаете, что делаете (и если вы это сделали, вы все равно не будете смешивать эти вещи).

Ответ 3

В С++ использование удаления в свободную память, полученное с помощью malloc(), не обязательно приводит к взрыву программы.

Вы никогда не должны этого делать. Хотя некоторый компилятор выделяет память для нового, используя malloc, free() не вызывает деструкторы. Поэтому, если вы смешиваете "новый" со "свободным", вы получите утечки памяти и много проблем с проблемами. Просто забудь это. Это не стоит усилий.

Вы, ребята, думаете, что предупреждение или, возможно, даже отказ от утверждения должны быть получены, если удаление используется для освобождения памяти, полученной с помощью malloc()??

Насколько я знаю, на MSVC, пытающемся удалить() память, выделенную с помощью malloc, генерирует ошибку отладки (что-то вроде "pCrtBlock недействительно", хотя я не помню точного сообщения). То есть - если проект был построен с помощью отладочных библиотек crt. Бывает, потому что debug new() выделяет дополнительную память для каждого выделенного блока, и этот блок не существует в памяти, выделенной с помощью malloc.

Почему вы думаете, что Stroustup не использовал эту функцию на С++?

По-моему, потому, что программисту должно быть разрешено стрелять в ногу с ракетной установкой, если он действительно хочет это сделать. delete() даже не предполагается совместимым с malloc, поэтому добавление защиты от полной глупости не стоит усилий для создания функции.

Ответ 4

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

Его еще очень плохая практика, чтобы сделать это, даже если ваша программа не сбой...

Ответ 5

Лично поведение undefined схем смешивания и сопоставления памяти позволяет нежелательно смешивать их в одной программе/библиотеке.

Существуют некоторые инструменты статического анализа, которые могут идентифицировать этот дисбаланс распределения памяти/освобождения памяти и генерировать предупреждения для вас. Однако статический анализ никогда не бывает на 100% точным или безупречным, так как всегда будут ограничения в способности инструментов отслеживать переменные и места памяти в программе.

Полное раскрытие: я работаю в Red Lizard Software, пишущий инструмент статического анализа goanna для C/С++ и способен обнаруживать этот вид несоответствия в некоторых, а не во всех случаях.

Ответ 6

Я не знаю, почему компиляторы не делают этого, это кажется полезным.

Компилятор может определенно связывать бит данных с каждым указателем (выделенным с новым или выделенным с помощью malloc или неизвестным), и когда он обнаружит свободный или удаленный, если распределение не соответствует, оно может выдать предупреждение. Не было бы накладных расходов на выполнение этого во время выполнения. Он не поймал бы всех ошибок, но он поймал бы некоторых, поэтому будет полезно.

Во время выполнения среда выполнения С++ уже содержит много дополнительной информации о некоторых компиляторах для перехвата буферов и т.д. в сборках отладки, поэтому я не понимаю, почему она не может добавить флаг в блок памяти, чтобы сказать как он был выделен и как-то сообщать об ошибке, если он терпит неудачу.

Я полагаю, что реальный ответ заключается в том, что он вообще поймает множество ошибок. Кажется, здесь очень много вопросов с новым каждый день о смешивании новых и malloc, и все же за 10 лет программирования я никогда не видел программу, которая это делает. C-программы используют malloc, С++-программы используют новые, и я почти никогда не видел их смешанными. Если вы используете С++, вы просто используете новое для всего. Я предполагаю, что есть устаревший код, который изначально был C повторно использован в С++, но я сомневаюсь, что этого достаточно, чтобы это было большой проблемой в реальной жизни.

У кого-нибудь была проблема с этим в реальной программе?

Ответ 7

Нет.

При программировании компилятора предупреждения являются второй сложнейшей задачей для разработки.

Поэтому у вас обычно есть предупреждения против важных тинов, как в "что-то, что действительно может случиться с профессионалом", а не в огромном разнообразии совершенно немого злоупотребления API. Кроме того, malloc и новые выделенные указатели во время компиляции невозможно отличить.

Ответ 8

Нет. Предупреждение не может быть создано, потому что невозможно определить, был ли указатель назначен кусок памяти из malloc, новый или просто указывает где-то во время компиляции.

Утверждение - хорошая функция, поэтому проверка границ массива, проверка указателя NULL и т.д., но С++ - неуправляемый язык программирования и предполагает, что вы знаете, что вы делаете.

Ответ 9

Нет. Не может быть сделано. Я могу (законно и в соответствии со спецификацией) перегружать new() и delete(), чтобы использовать malloc и бесплатно (как я это делал раньше), и в этот момент это не совсем понятно, что сделало бы со мной ваше утверждение.