Может ли новый по-прежнему вызывать исключение?

Я начинающий программист на C++, поэтому я никогда не писал код на C++ для чего-то старше C++11. Я читал Скотта Мейерса «Эффективный С++, 2-е издание» (я знаю, что он старый, но я думаю, что в нем все еще есть некоторые важные моменты).

В книге, согласно «Пункту 7», new может генерировать исключения, которые следует обрабатывать.

Может ли new по-прежнему создавать исключения?

Должен ли я быть готов к исключениям, которые могут быть вызваны умным указателем или new?

При использовании интеллектуальных указателей избегайте использования new. Вместо этого используйте функции make_unique и make_shared. Они выполняют нетривиальную очистку, если им не удастся создать экземпляр или что-то еще пойдет не так.

user4581301 17.05.2022 20:48

Вы все равно не должны использовать new напрямую почти во всех случаях, частично именно потому, что трудно сделать его использование безопасным для исключений. В отличие от интеллектуальных указателей, это не гарантирует, что объекты newed уничтожаются, а память освобождается автоматически при возникновении исключения (вне самого выражения new).

user17732522 17.05.2022 20:49

@user4581301 user4581301 вопрос был конкретно об использовании new; вы не знаете его дела. Бывают ситуации, когда интеллектуальные указатели не подходят/невозможны.

Inigo Selwood 17.05.2022 20:50

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

Eljay 17.05.2022 20:52

Также обратите внимание, что готовность к возникновению исключений не означает, что вы должны ставить try/catch при каждом использовании new. Вам нужно только перехватывать исключения, когда вашей программе имеет смысл восстановиться после сбоя. (Как упоминалось выше для std::bad_alloc из new, это часто нигде.) Однако вы должны убедиться, что код безопасен для исключений и не допускает утечки памяти или других ресурсов в случае возникновения исключения.

user17732522 17.05.2022 20:52

@InigoSelwood комментарий просто предназначен для ответа на последнюю строку вопроса. Если бы это была законченная мысль и ответ, я бы написал ответ. Хотя при втором чтении это не такой полезный комментарий, как я думал. Спрашивающий, похоже, не спрашивает о new с умными указателями. Я должен был обратить больше внимания на или.

user4581301 17.05.2022 20:55

@Eljay Пожалуйста, дайте определение fault the program. Насколько я понимаю, настольные ОС не перегружают память виртуальный, поэтому они всегда смогут выполнить свои обещания... в конце концов. Кроме того, std::bad_alloc может возникнуть в результате превышения какой-либо квоты, хотя, вероятно, ее еще нельзя восстановить.

Paul Sanders 17.05.2022 20:58

@blank, вам не нужно помечать все эти версии языка C++, поэтому я удалил их. Эти теги предназначены для случаев, когда вас интересует (или ограничивает) версия (или версии) конкретный.

Paul Sanders 17.05.2022 21:23

@PaulSanders • Мое понимание — и опыт — состоит в том, что ОС для настольных ПК действительно выделяют виртуальную память и могут вызвать ошибку программы, если они не смогут предоставить обещанную память. Частично в этой ситуации можно обвинить программы, которые являются «плохими гражданами», потому что они чрезмерно запрашивают память кучи, что является обычной практикой. В совокупности память становится перегруженной, что обычно не является проблемой, пока в редкой ситуации (на практике) это не становится проблемой. Но это будет намного позже, чем new, казалось бы, удалось.

Eljay 17.05.2022 23:14

@Eljay Кажется, это зависит от платформы (что я подозревал): superuser.com/questions/1194263/…. Должен сказать, я предпочитаю подход Windows.

Paul Sanders 17.05.2022 23:56

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

Paul Sanders 18.05.2022 00:17
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
0
11
75
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Да, при распределении new может вызвать исключение bad_alloc.

То есть, если вы не передадите const std::nothrow_t& в качестве второго параметра, где вам будет гарантировано возвращаемое значение nullptr

См. подробности здесь

Могут ли умные указатели генерировать исключение?

Blank 17.05.2022 21:00

@ Пусто, да. Даже с умным указателем что-то может пойти не так и понадобится контекстная информация, недоступная конструктору создаваемого класса (например, конструктору нужно открыть файл, а он не может. Что тогда делать?) или вышеупомянутое bad_alloc. Интеллектуальный указатель обеспечит правильную очистку выделения и самого интеллектуального указателя, но вам все равно придется иметь дело с выброшенным исключением так или иначе.

user4581301 17.05.2022 21:09

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

François Andrieux 17.05.2022 23:38

@FrançoisAndrieux Интересно, но, возможно, не совсем неожиданно. Добавление кода для обработки такого (потенциального) исключения значительно усложнит nothrownew и (что более важно) добавит накладные расходы.

Paul Sanders 18.05.2022 00:50

Другие вопросы по теме