Подтвердить что ты не робот

Существует ли эквивалент С++ для исключения NullPointerException

И Java, и С#, и, возможно, многие другие языки тоже имеют предопределенный класс исключений, который вызывается, когда нулевой параметр используется там, где он не должен. Есть ли что-то подобное в С++? Если нет, существует ли еще одно предопределенное исключение, которое я могу использовать или я должен определить свой собственный?

4b9b3361

Ответ 1

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

std::invalid_argument

исключение (предоставить ему значимое значение - "p is NULL"), но вам нужно будет выполнить проверку самостоятельно.

Ответ 2

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

Лучше всего предотвратить ситуацию, чем попытаться восстановить ее (что не может быть сделано на C или С++ в любом случае).

Обычный шаблон для предотвращения некоторых связанных ошибок программиста заключается в использовании assert() внутри функциональных объектов, таких как:

int foo(int* myint)
{
  // Ensure myint is not NULL
  assert(myint);

  // Do something with myint
  (*myint)++;

  return *myint;
}

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

Ответ 3

В С++ нет стандартного исключения для разыменования указателя NULL.

Если вы этого хотите, вы можете реализовать его самостоятельно. В UNIX настройте обработчик сигнала SIGSEGV и исключите из обработчика исключение. В Windows используйте API _set_se_translator() для установки обработчика "Структурированное исключение".

Ответ 4

FTR, в С# вы не используете NullReferenceException для чего-либо, если вы не хотите, чтобы вас закололи ваши товарищи по команде. Вместо отклонения нулевых аргументов существует ArgumentNullException. NREs должны быть выброшены во время выполнения, а не вы.

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

Ответ 5

Почти во всех случаях, связанных с неправильным использованием нулевого указателя (esp., deefencing it), стандарт С++ просто оставляет поведение undefined. Конкретный тип исключения не предусмотрен (и исключение не будет выбрано).

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

std::function<void(int)> func = nullptr;

И если вы затем попытаетесь вызвать функцию, завернутую им, выполнив func(arg); для некоторого аргумента arg, он выкинет исключение std::bad_function_call.

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

Ответ 6

В С++ разыменование нулевой указатель приведет к поведению undefined, что в основном заканчивается приложением с ошибкой сегментации. В Visual Studio вы можете использовать расширения, такие как Structured Exception Handling (SEH), которые позволяют улавливать разыменование нулевого указателя.

Ответ 7

Вы можете заключить указатель в класс шаблона, который предоставляет ограниченный интерфейс для указателя. Он может выполнять проверку nullptr всякий раз, когда вы обращаетесь к указателю, и выдавать исключение.