views:

1159

answers:

7
  try {
        int* p = 0;
        *p = 1;
    } catch (...) {
        cout << "null pointer." << endl;
    }

I tried to catch the exception like this but it doesn't work,any help?

+3  A: 

You cannot. De-referencing a null-pointer is a system thing.

On Linux, the OS raises signals in your application. Take a look at csignal to see how to handle signals. To "catch" one, you'd hook a function in that will be called in the case of SIGSEGV. Here you could try to print some information before you gracefully terminate the program.

Windows uses structured-exception-handling. You could use the instristics __try/__except, as outlined in the previous link. The way I did it in a certain debug utility I wrote was with the function _set_se_translator (because it closely matches hooks). In Visual Studio, make sure you have SEH enabled. With that function, you can hook in a function to call when the system raises an exception in your application; in your case it would call it with EXCEPTION_ACCESS_VIOLATION. You can then throw an exception and have it propagate back out as if an exception was thrown in the first place.

GMan
You must also use `/EHa` when using `_set_se_translator`.
Pavel Minaev
Hey, I said that :P
GMan
I find `_set_se_translator` is only of limited use because (from msdn) ... "In a multithreaded environment, translator functions are maintained separately for each thread. Each new thread needs to install its own translator function. Thus, each thread is in charge of its own translation handling. _set_se_translator is specific to one thread; another DLL can install a different translation function." ... So if you don't control the creation of all threads that call your code you cannot use it. Having said that boost.test uses this to great effect, but this is single threaded
iain
+4  A: 

C++ doesn't do pointer checking (although I suppose some implementations could). If you try to write to a null pointer it is most likely going to crash hard. It will not throw an exception. If you want to catch this you need to check the value of the pointer yourself before you try to write to it.

Nate C-K
It really depends on the implementation and the OS. E.g. on Win32, dereferencing a null pointer will result in an access violation (as any other platform with memory protection, really), but Win32 AV is a structured exception, and it can be caught by a C++ compiler that implements its own exception model on top of Win32 SEH - for example, VC++ with `/EHa` compilation flag. Of course, it is still sheer evil (and unportable).
Pavel Minaev
Speaking of memory protection, I started writing C on DOS, when writing to a null pointer usually meant you'd be rebooting your machine. At least DOS booted fairly quickly.
Nate C-K
+3  A: 

Dereferencing a null (or pointer that's past-the-end of array, or a random invalid pointer) results in undefined behavior. There's no portable way to "catch" that.

Pavel Minaev
+1  A: 

As others have said, you can't do this in C++.

If I can make a broader point: even in a language that allows you to catch it, the better action is to not touch null pointers. Catching an error when it's already blown up in your face, then deciding to just move on like it didn't happen, is not a good coding strategy. Things like null pointer dereference, stack overflow, etc., should be seen as catastrophic events and defensively avoided, even if your language allows you to react to it differently.

asveikau
A: 

There is no platform independent way to do this. Under Windows/MSVC++ you can use __try/__except

But I wouldn't recommend doing it anyway. You almost certainly cannot recover correctly from a segmentation fault.

Axel Gneiting
He's specifically asking about null pointer dereference, which is certainly quite recoverable (as it doesn't corrupt memory etc). Still not a good idea, but for different reasons.
Pavel Minaev
Indeed, the only exception I had a bit difficulty from recovering from was a stack-overflow. In fact, I couldn't. I don't think it's possible, as throwing an exception uses too much stack, at least on Windows (Linux provides an alternate stack for exceptions). You do have enough time to spawn a new thread and try to save as much information as you can, though.
GMan
I don't agree that it is recoverable, since it represents a logical error in the program, and the only way to fix logical errors is to alter the program itself.It's trappable, but trappable doesn't mean recoverable.If your program detects a logical error, such as this, it should crash early, crash often.
DrPizza
+6  A: 

There's no such thing as "null pointer exception" in C++. The only exceptions you can catch, is the exceptions explicitly thrown by throw expressions (plus, as Pavel noted, some standard C++ exceptions thrown intrinsically by standard operator new, dynamic_cast etc). There are no other exceptions in C++. Dereferencing null pointers, division by zero etc. does not generate exceptions in C++, it produces undefined behavior. If you want exceptions thrown in cases like that it is your own responsibility to manually detect these conditions and do throw explicitly. That's how it works in C++.

Whatever else you seem to be looking for has noting to do with C++ language, but rather a feature of particular implementation. In Visual C++, for example, system/hardware exceptions can be "converted" into C++ exceptions, but there's a price attached to this non-standard functionality, which is not normally worth paying.

AndreyT
"The only exceptions you can catch, is the exceptions explicitly thrown by throw expressions" - and default `operator new` (it may be implemented using explicit `throw`, sure, but there's nothing that requires it to do that; it may well be an intrinsic).
Pavel Minaev
There are more places in C++ that can throw besides `operator new`, `dynamic_cast` to reference type being another example, but that wasn't the point. The point is that you can only catch C++ exceptions. Of course, claiming that they can only be thrown by a user-level `throw` is incorrect.
AndreyT
+1  A: 

Generally you can't. Even if you could it would be like trying to put a band aid on a submarine that has sprung a leak.

A crippled application can do far more damage than one that has crashed. My advise here would be to let it crash then fix why it crashed. Rinse. Repeat.

0xC0DEFACE