Если вы работаете на типичном встроенном процессоре под управлением Linux без виртуальной памяти, вполне вероятно, что ваш процесс будет остановлен операционной системой до того, как произойдет сбой нового, если вы выделите слишком много памяти.
Если вы запускаете свою программу на компьютере с меньшим объемом физической памяти, чем максимальный размер виртуальной памяти (2 ГБ в стандартной Windows), вы обнаружите, что, как только вы выделите объем памяти, приблизительно равный доступной физической памяти, дальнейшее распределение будет выполнено успешно, но вызовет подкачку на диск. Это замедлит вашу программу, и вы, возможно, не сможете добраться до точки исчерпания виртуальной памяти. Таким образом, вы можете не получить исключение.
Если у вас больше физической памяти, чем у виртуальной памяти, и вы просто продолжаете выделять память, вы получите исключение, когда вы исчерпали виртуальную память до такой степени, что вы не сможете выделить размер запрашиваемого блока.
Если у вас есть длительно работающая программа, которая выделяет и освобождает блоки разных размеров, включая небольшие блоки, с большим разнообразием времени жизни, виртуальная память может стать фрагментированной до такой степени, что новые не смогут найти большой достаточно блока, чтобы удовлетворить запрос. Тогда новый бросит исключение. Если у вас случится утечка памяти, из-за которой случайный маленький блок будет вытекать в случайном месте, что в конечном итоге приведет к фрагментации памяти до такой степени, что произойдет сбой при произвольно малом выделении блока, и возникнет исключение.
Если у вас есть программная ошибка, которая случайно передает огромный размер массива в new [], new завершится ошибкой и выдаст исключение. Это может произойти, например, если размер массива на самом деле является своего рода случайным байтовым шаблоном, возможно, полученным из неинициализированной памяти или поврежденного потока связи.
Все вышеперечисленное относится к глобальному новому по умолчанию. Однако вы можете заменить глобальный новый, и вы можете предоставить новый для конкретного класса. Их тоже можно выбросить, и смысл этой ситуации зависит от того, как вы ее запрограммировали. Обычно new включает цикл, который пытается получить все возможные пути для получения запрошенной памяти. Он бросает, когда все они исчерпаны. То, что вы делаете, зависит от вас.
Вы можете перехватить исключение из нового и использовать предоставляемую им возможность для документирования состояния программы во время возникновения исключения. Вы можете "сбросить ядро". Если у вас есть циклический инструментарий буфера, выделенный при запуске программы, вы можете сбросить его на диск, прежде чем завершить программу. Завершение программы может быть изящным, что является преимуществом по сравнению с просто не обработкой исключения.
Я лично не видел пример, где дополнительная память могла быть получена после исключения. Одна из возможностей, однако, заключается в следующем. Предположим, у вас есть распределитель памяти, который очень эффективен, но не хорош для освобождения свободного места. Например, он может быть подвержен фрагментации свободного пространства, в которой свободные блоки являются смежными, но не объединяются. Вы можете использовать исключение из new, перехваченное в new_handler, чтобы запустить процедуру сжатия для свободного места перед повторной попыткой.
Серьезные программы должны рассматривать память как потенциально дефицитный ресурс, максимально контролировать ее распределение, следить за ее доступностью и соответствующим образом реагировать, если что-то, по-видимому, пошло не так. Например, вы могли бы привести случай, когда в любой реальной программе верхняя граница параметра размера, передаваемого распределителю памяти, довольно мала, и все, что больше этого, должно вызывать некоторую обработку ошибок, независимо от того, может ли быть выполнен запрос. довольный. Можно утверждать, что скорость увеличения памяти долго работающей программы следует отслеживать, и если можно разумно предсказать, что программа исчерпает доступную память в ближайшем будущем, следует начать упорядоченный перезапуск процесса.