В использовании C++ delete
к свободной памяти, полученной с malloc()
не обязательно заставляет программу аварийно завершаться.
Если предупреждение или возможно даже отказ утверждения должны быть произведены если delete
привык к свободной памяти, полученной с помощью malloc()
?
Почему у Stroustrup не было этой функции на C++?
В C ++ использование delete для освобождения памяти, полученной с помощью malloc (), не обязательно приводит к сбою программы.
Нет, но это обязательно приводит к неопределенному поведению, что означает, что может произойти что угодно, в том числе взорвется программа или программа продолжит работу, что кажется правильным.
Как вы думаете, должно ли быть выдано предупреждение или, возможно, даже ошибка утверждения, если для освобождения памяти, полученной с помощью malloc (), используется удаление?
Нет. Это сложно, если вообще возможно, проверить во время компиляции. Проверки во время выполнения дороги, а в C ++ вы не получаете того, за что не платите.
Это может быть полезным параметром для включения во время отладки, но на самом деле правильный ответ - просто не смешивать и не сопоставлять их. У меня ни разу не было с этим проблем.
Предупреждение было бы неплохо, но этого, вероятно, не происходит, потому что C++ изначально был построен на C, поэтому ошибка выполнения не может быть сгенерирована, потому что malloc
является допустимым C.
Это все еще крайне плохая практика, чтобы сделать это, даже если ваша программа не падает ...
Нет.
При программировании компилятора предупреждения - вторая вещь, которую сложнее всего разработать.
Таким образом, у вас обычно есть предупреждения о важных вещах, например, о «чем-то, что действительно может случиться с профессионалом», а не о большом разнообразии совершенно глупого неправильного использования API. Кроме того, во время компиляции может быть невозможно различить malloc и новые выделенные указатели.
delete
имеет специальное свойство, которого free ()
не имеет: он вызывает деструкторы, которые, в свою очередь, могут вызывать больше удалений поскольку этот объект мог выделить другие вещи в куче.
При этом new
также вызывает конструктор объекта, а malloc ()
- нет. Не смешивайте эти вещи, если вы абсолютно не уверены, что знаете, что делаете (а если бы вы это сделали, вы бы все равно не смешивали эти вещи).
В C ++, используя удаление для свободная память, полученная с помощью malloc (), не обязательно приводит к сбою программы.
Вы никогда не должны этого делать. Хотя некоторые компиляторы выделяют память для новых с помощью malloc, free () не вызывает деструкторы. Так что, если вы смешаете «новое» с «бесплатным», вы получите утечку памяти, и вам будет сложно справиться с проблемами. Просто забудь это. Это не стоит усилий.
Как вы думаете, должно ли быть выдано предупреждение или, возможно, даже ошибка утверждения, если для освобождения памяти, полученной с помощью malloc (), используется удаление?
Насколько мне известно , в MSVC при попытке удалить ( ) память, выделенная с помощью malloc, генерирует ошибку отладки (что-то вроде «pCrtBlock недействителен», хотя я не помню точное сообщение). То есть - если проект был собран с использованием отладочных библиотек crt. Это происходит из-за того, что debug new () выделяет дополнительную память для каждого выделенного блока, а этот блок не существует в памяти, выделенной с помощью malloc.
Как вы думаете, почему у Страуструпа не было этой функции на C ++?
На мой взгляд, потому что программисту должно быть разрешено стрелять себе в ногу из гранатомета, если он действительно хочет этого. delete () даже не должен быть совместим с malloc, поэтому добавление защиты от полной глупости не стоит усилий по созданию функции.
Я не знаю, почему компиляторы не делают этого, кажется, это полезно.
Компилятор, безусловно, может связать бит данных с каждым указателем, говорящим (выделенный с помощью new или выделенный с помощью malloc или unknown), и когда он обнаруживает свободное или удаление, если распределение не совпадает, он может выдать предупреждение. Выполнение этого во время выполнения не приведет к накладным расходам. Он не улавливает все ошибки, но он может обнаружить некоторые, поэтому будет полезен.
Во время выполнения среда выполнения C ++ уже помещает много дополнительной информации в некоторые компиляторы для обнаружения переполнения буфера и т. Д. В отладочных сборках, поэтому я не понимаю, почему она не может добавить флаг в блок памяти, чтобы сказать как он был распределен и как-то сообщить об ошибке, если он не работает.
Я полагаю, что реальный ответ состоит в том, что он вообще может отловить много ошибок.Кажется, здесь очень много вопросов с новым каждый день о смешивании new и malloc, и все же за 10 лет программирования я ни разу не видел программы, которая бы это делала. В программах на C используется malloc, в программах на C ++ - new, и я почти никогда не видел, чтобы они смешивались. Если вы используете C ++, вы просто используете new для всего. Я предполагаю, что существует устаревший код, который изначально был C и был повторно использован в C ++, но я сомневаюсь, что этого достаточно, чтобы это стало большой проблемой в реальной жизни.
У кого-нибудь вообще были проблемы с этим в реальной программе?
Нет. Предупреждение не может быть выдано, потому что во время компиляции невозможно определить, был ли указатель присвоен части памяти из malloc, new или просто указывает куда-то.
Утверждение - это хорошая функция, как и проверка границ массивов, проверка указателей NULL и т.д., но C++ - неуправляемый язык программирования и предполагает, что вы знаете, что делаете.
Лично неопределенное поведение смешивания и сопоставления схем распределения памяти делает нежелательным даже смешивание их в одной программе / библиотеке.
Есть несколько инструментов статического анализа, которые могут идентифицировать этот вид дисбаланса выделения / освобождения памяти и генерировать предупреждения для вас. Однако статический анализ никогда не бывает на 100% точным или надежным, так как всегда будут ограничения в способности инструментов отслеживать переменные и ячейки памяти в программе.
Полное раскрытие: я работаю в Red Lizard Software , пишу инструмент статического анализа goanna для C / C ++, и он способен обнаруживать такого рода несоответствия в некоторых, а не во всех случаях.