Когда следует использовать std :: nothrow? - PullRequest
30 голосов
/ 18 января 2011

Что такое идеальное использование std::nothrow?

Ответы [ 9 ]

11 голосов
/ 18 января 2011

Я бы использовал его только как оптимизацию (или упрощение кода), когда в противном случае я бы немедленно поместил блок try-catch вокруг использования обычного нового, перехватывая std::bad_alloc.

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

Может случиться так, что ошибка действительно может быть немедленно обработана.Например, вы можете оказаться в ситуации, когда вы будете использовать один алгоритм или метод с достаточным рабочим пространством, а другой, более медленный алгоритм или метод без него.Опять же, вы бы выделяли такое рабочее пространство непосредственно с new?Не нормально.И в любом случае вам иногда нужно быть осторожным с этим подходом, потому что если ваша ОС перегружена, то в целом вы не можете изящно обработать нехватку памяти на уровне приложения.

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

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

9 голосов
/ 18 января 2011

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

9 голосов
/ 18 января 2011

Насколько я понимаю, почти никогда.

4 голосов
/ 18 января 2011

Вы используете std :: nothrow, когда хотите проверять наличие нуля после каждого нового.Много устаревшего кода нуждалось в этом, когда была сделана первая версия стандарта.Много унаследованного кода, написанного впоследствии, тоже используют его, потому что люди были параноидальными исключениями.Время от времени вы сталкиваетесь с кем-то, кто все еще существует.

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

4 голосов
/ 18 января 2011

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

Имейте в виду, что Страуструп довольно непреклонен, что программист может отключитьнакладные расходы в C ++.(Однако, как предостережение, то, что у вас есть выбор, не означает, что вы должны это делать.)

3 голосов
/ 18 января 2011

Я знаю, что были более старые версии C ++ (в частности, Microsoft), которые не выдавали, когда не могли выделить память, но вместо этого возвращали NULL.Это был бы простой способ поддерживать совместимость со старым кодом, а не изменять всю логику.

1 голос
/ 18 января 2011

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

1 голос
/ 18 января 2011

http://www.cplusplus.com/reference/std/new/nothrow/

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

Тем не менее, я обычно предпочитаю общий вариант.

0 голосов
/ 28 августа 2013

Лишь очень немногие программы должны когда-либо выделять более 1 ГБ памяти, а поскольку современные системы перегружают память, new никогда не вернет ноль или сброс в этих системах.Следовательно, абсолютно нет смысла проверять возвращаемое значение new / malloc.Просто уменьшите объем памяти и позвольте убийце нехватки памяти сбивать другие процессы!

...