Is there a C++ equivalent of a NullPointerExceptio

2020-03-08 07:58发布

问题:

Both Java and C#, and probably many other languages too, have a predefined exception class that is thrown when a null parameter is used where it should not. Is there anything similar in C++? If not, is there another predefined exception I can use or should I define my own one?

回答1:

Dereferencing a NULL pointer is undefined behaviour in C++ - which means the code can appear to work. An exception isn't guaranteed to be thrown. You can use the

std::invalid_argument

exception (provide a meaningful value to it - "p is NULL"), but you'll have to do the check yourself.



回答2:

Usually, in C++ (or C for that matter), you never dereference a NULL pointer. Doing this has undefined behavior (likely a segfault on any implementation I know of, but anything could happen according to the standard). It's probably a bad thing in other languages as well, but I don't know those enough to assert that.

It's best to prevent the situation than to try to recover from it (which can't be done in C or C++ anyway).

The usual pattern to prevent some related programmer errors is to use assert() inside function bodies such as:

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

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

  return *myint;
}

Such assert() calls are completely ignored on release builds and thus have no cost in production. They just help the development. On debug builds, and if the condition is not met, the program aborts immediately with a very explicit error message. Running it through a debugger, you can easily check the call stack to investigate for the exact reason.



回答3:

There is no standard exception in C++ for dereferencing a NULL pointer.

If you want it, you can implement it yourself. On UNIX set up a SIGSEGV signal handler and throw an exception from the handler. On Windows, use the _set_se_translator() API to install a "Structured Exception" handler.



回答4:

FTR, in C# you don't use NullReferenceExceptions for anything unless you want to get stabbed by your team mates. There is a ArgumentNullException instead for rejecting null arguments. NREs are meant to be thrown by the runtime, not you.

But note that there is no actually advantage of this over an assertion because you should not be catching one of these: if they are thrown, they indicate a bug. These are what Eric Lippert calls boneheaded exceptions and they are your own darn fault, and there is nothing your code should be doing specifically with them.



回答5:

In nearly all cases that involve wrongly using a null pointer (esp., derefencing it), the C++ Standard simply leaves the behaviour undefined. No specific exception type is provided for (and no exception will be thrown).

One possible exception to this rule comes to mind, though. std::function, which is a C++11 standard-library template that can be used to wrap functions, can be assigned a null pointer:

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

And if you then make an attempt to call the function wrapped by it by doing func(arg); for some argument arg, it will throw a std::bad_function_call exception.

This is, of course, not fully equivalent to the null pointer exceptions of other languages, because it is far less generally applicable.



回答6:

Under C++ dereferencing null pointer will result in undefined behaviour, what mostly ends application with segmentation fault. Under Visual Studio you can use extensions like Structured Exception Handling (SEH), that allow to catch null pointer dereferencing.



回答7:

You can wrap a pointer in a template class which provides a limited interface to the pointer. It can do a nullptr check whenever you access the pointer, and throw an exception.