I'm trying to safely recover from a segmentation fault I expect to happen. I'm trying to avoid it checking using my canAlloc() function here. When canAllow returns false, A0 (which is Ackermann's if you didn't see it) should throw an exception that I can catch in the main method. checkTable and saveInTable are both functions that use a map<int hash, int value> to store returns from A0.
bool canAlloc(){
bool reBool = false;
int * memch = (int*)calloc (10000, sizeof(int));
reBool = (memch != NULL);
free(memch);
return reBool;
}
int A0(int m, int n){
if(!canAlloc()) throw;
int reInt = checkReturnTable(m,n);
if(reInt == -1){
if(m == 0){
return n + 1;
} else if(m > 0){
if(n == 0){
reInt = A0(m-1,1);
} else if(n > 0){
reInt = A0(m-1, A0(m,n-1));
}
}
saveInReturnTable(m,n,reInt);
return reInt;
} else return reInt;
}
From a comment:
In main I have a try-catch block to catch any exception try{} catch(...){}. As I understand it the three periods should catch any exception thrown. And as I understand, the throw keyword throws the exception without any specifiers, but can still be caught by the three dots.
A segmentation fault is not a C++ exception. It is indicative of a program failure that causes the OS to send a SIGSEGV signal to your process. You won't be able to catch a SIGSEGV signal directly; you'd have to set up a signal handler and ... well, it gets tricky at that point, because it is not clear that you can throw an exception from within a signal handler.
A throw with no exception specified rethrows the current exception; it only makes sense inside a catch block.
You probably get the SIGSEGV when your system is unable to extend the stack any further, probably because you've run out of virtual memory. That means one of your function calls failed because there was no space to put its arguments or local variables or return address, etc. There is no clean way to recover from that, which is why the system generates the segmentation fault.
If the fault was because calloc() could not allocate memory, you'd not get a segmentation fault; you'd get a zero return value. And you could raise an 'out of memory' exception cleanly and synchronously when it happens. But that isn't your problem.
You cannot recover from a segmentation fault, because once the fault occurs, your program is no longer in a well-defined state, and there's no mechanism to roll back to a well-defined state, either.
A segmentation fault is always a programming error in one way or another, and you must simply avoid it. In C++, you can simply catch exceptions coming from a dynamic allocation:
T * p;
try { p = new T; }
catch(const std::bad_alloc & e) { /* ... */ }
Usually there's no need to be quite that manual, though, since you would wrap your dynamic allocations inside suitable managing containers (like unique_ptr or shared_ptr), and you should catch exceptions (not even just allocation ones) at points in your program flow where you are in a position to handle the error and continue meaningfully.
(Thanks to exceptions you should not usually need to check the result of possibly throwing functions right at the call side - that's the whole point of using exceptions.)
If for some reason you just want to allocate raw memory, without constructing any object, you can do it in two ways:
// Method #1, the C++ way:
void * addr = ::operator new(n); // will throw std::bad_alloc on error
// Method #2, the manual way:
void * addr = std::malloc(n);
if (!addr) throw std::bad_alloc(); // throw exception manually, handled elsewhere
Related
I have following code snippet:
try
{
if(/*something is true*/)
{
throw Win32Error(msgWin32Error->GetError()); //assume msgWin32Error is NULL
}
}
catch (Win32Error& win32Error)
{
}
Assuming msgWin32Error is NULL in above code snippet, when throw statement gets executed, it will have another exception in turn. What will be the behavior in such circumstance?
Thanks,
Su
There will be no C++ exception here.
You are conflating two things:
C++ exceptions (see: throw, try, catch)
Runtime errors invoked by the operating system (e.g. segmentation fault)
The latter are sometimes also confusingly called "exceptions", but you cannot catch these with C++ catch.
What will happen is that the dereference of msgWin32Error will (probably) cause the Operating System to terminate your application. Control will never even reach your throw instruction.
First of all, when you dereference a NULL pointer, you get undefined behavior. An exception might be thrown (because throwing an exception is in the list of allowable behaviors if UB is invoked), but you can't count on that. However, it's easy to construct a well defined example that gets at what I think you are asking.
char const* foo()
{
throw ExceptionZ();
return "message";
}
void bar()
{
try
{
throw ExceptionX(foo());
}
catch(ExceptionX) { ... }
catch(ExceptionZ) { ... }
}
In this case, the handler for ExceptionZ will be entered. The throw statement in bar does not complete. The exception thrown from foo() propagates before it can.
I want to have a function which dynamically creates and returns a 2D array or when memory allocation fails passes the exception without information loss after cleaning up already allocated rows:
double **create (int rows, int cols)
{
double **array = new double* [rows];
for (int x=0; x<rows; x++)
{
try { array[x] = new double [cols]; }
catch (exception &e)
{
x--;
for (; x>=0; x--)
delete[] array[x]; // clean up already allocated rows
delete[] array;
throw e; // pass exception
}
for (int y=0; y<cols; y++)
array[x][y] = 0; // initialize array
}
return array;
}
So I can be sure, if create throws, there is no memory leak. But can I be sure, that the passed exception e is "the same" as if directy thrown by new and not catched?
E.g.
int main ()
{
double **d;
try { d = create (HUGE_x, HUGE_y); }
catch (exception &e)
{
// 1. e could be thrown by new double* [rows]
// e.g. if HUGE_x is already to huge
// 2. e could be thrown by throw e
// e.g. if after some rows no memory anymore
// in both cases: is e the same?
}
return 0;
}
Or is it necessary to have catch (bad_alloc &e) inside the create function? Or does it work only with catch (...) { /* do clean-up*/ throw; }? Is there the same problem as in C# with losing stack trace when re-throw is not with throw; simply?
And another, more general question:
void f () { throw Object(); } // or throw "help";
void main ()
{
try { f(); }
catch (Object &e) // or catch (char *)
{
// Where is the Object or C-String created on the stack in function f()
// since we aren't any more in function f() but we are dealing with
// references/pointers to a non-existent stack?
}
}
For exception-safe memory management, use RAII. Rather than juggling raw pointers and exception handlers, assign the resource to a class which will release it on destruction. That way, everything is cleaned up automatically if an exception is thrown.
In this case, std::vector is a suitable RAII class managing a dynamic array:
vector<vector<double>> create (int rows, int cols) {
return vector<vector<double>>(rows, vector<double>(cols));
}
(Note that it may be more efficient to represent the 2D array as a single array of size rows*cols, with accessors to provide 2D indexing into it. But that's off-topic for this question, so I won't go into tedious detail).
To answer your questions, although they're largely irrelevent if you write exception-safe code:
But can I be sure, that the passed exception e is "the same" as if directy thrown by new and not catched?
It won't be; you're throwing a new object, created by copying or moving e, with type exception.
Or is it necessary to have catch (bad_alloc &e) inside the create function?
Then you won't catch other types of exceptions. In this case, that might not a problem, but you really want to be catching all exceptions if you're going to be cleaning up like this. To reiterate: don't use exception handlers to clean up. It's very error-prone.
Or does it work only with catch (...) { /* do clean-up*/ throw; }?
That will rethrow the original object, which is what you want. (Except that you shouldn't want to be catching anything in the first place).
Is there the same problem as in C# with losing stack trace when re-throw is not with throw; simply?
Standard exceptions don't give you a stack trace anyway. If you have a custom exception type with a stack trace, then it depends on whether it generates a new one when copied/moved, or copies/moves the existing one.
Where is the Object or C-String?
The exception handling mechanism creates it somewhere (not on the stack which is about to be unwound), and destroys it once it's been handled. It's not specified exactly where it is, just how it must work.
While this question is quite old by now and has been answered adequately, I would like to add a note on rethrowing exceptions.
In standard C++11 you can retain the original exception information by rethrowing with:
std::nested_exception and std::throw_with_nested
FYI: using this, you can also generate exception backtraces, as described on StackOverflow here and here, without need for a debugger or cumbersome logging, by simply writing a proper exception handler which will rethrow nested exceptions.
Since you can do this with any derived exception class, you can add a lot of information to such a backtrace!
You may also take a look at my MWE on GitHub, where a backtrace would look something like this:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"
I did bit of researching while trying to find proper way to implement exceptions in my code I came accross
Throw by value, catch by reference
to be the recommended way of deal exceptions in C++ . I have a confusion about when the exception thrown gets out of scope.
I have following exception hierarchy
ConnectionEx is mother of all connection exceptions thrown by dataSender
ConnectionLostEx is one of the subclasses of ConnectionEx
so here is a sample code. In words DataSender instance is member of DataDistrubutor who calls functions on dataSender for example send() and DataSender throws ConnectionEx's subclasses as exceptions in case of problems.
// dataSender send() function code chunk
try
{
// some problem occured
// create exception on stack and throw
ConnectionLostEx ex("Connection lost low signals", 102);
throw ex;
}
catch(ConnectionLostEx& e)
{
//release resources and propogate it up
throw ;
}
//A data distributor class that calls dataSender functions
try
{
// connect and send data
dataSender.send();
}
catch(ConnectionEx& ex)
{
// free resources
// Is the exception not out of scope here because it was created on stack of orginal block?
//propogate it further up to shows cause etc..
}
In C# or java we have a pointer like reference and that it valid all the way up, I am confused about the scope of exceptions given the exception is thrown by value when exactly does it get out of scope ??? and when caught as parent type ConnectionEx in this case can this be casted to get the real one back somwhere up in the chain of catch blocks ??
A copy of the exception is thrown, not the original object. There's no need to instantiate a local variable and throw it; the idiomatic way to throw an exception is to instantiate it and throw it on the same line.
throw ConnectionLostEx("Connection lost low signals", 102);
I am new to programming and am having trouble with try / catch clauses.
Here is an example from a textbook that I have:
int main( )
{
char *ptr;
try {
ptr = new char[ 1000000000 ];
}
catch( … ) {
cout << "Too many elements" << endl;
}
return 0;
}
I have tried to look online for a further explanation and the textbook does not exactly tell me what what these clauses actually do or what it is used for.
Any information would be helpful.
EDIT: The textbook I am using is:
C++: Classes and Data Structures by Jeffrey Childs
A try-catch is the C++ construct for exception handling. Google 'C++ exceptions'.
Try catch is a way of handling exceptions:
try
{
// Do work in here
// If any exceptions are generated then the code in here is stopped.
// and a jump is made to the catch block.
// to see if the exception can be handled.
// An exception is generated when somebody uses throw.
// Either you or one of the functions you call.
// In your case new can throw std::bad_alloc
// Which is derived from std::runtime_error which is derived from std::exception
}
// CATCH BLOCK HERE.
The catch block is where you define what exceptions you want to handle.
// CATCH BLOCK
catch(MyException const& e)
{
// Correct a MyException
}
catch(std::exception const& e)
{
// Correct a std::exception
// For example this would cat any exception derived from std::exception
}
You can have as many catch blocks as you like. If you exception matches any of the catch expressions in the catch statement then the associated block of code is executed. If no catch expressions matches an exception then the stack is unwound until it finds a higher level catch block and the processes is repeated (this can cause the application to exit if no matching catch block is found).
Note: If multiple catch expressions match then the lexically first one is used. Only one or none of the catch blocks will be executed. If none then the compiler will look for a higher level try/catch.
There is also a catch anything clause
catch(...)
{
// This is a catch all.
// If the exception is not listed above this will catch any exception.
}
So how does this apply to your code.
int main( )
{
char *ptr;
try
{
// This calls ::new() which can potentially throw std::bad_alloc
// If this happens then it will look for a catch block.
ptr = new char[ 1000000000 ];
// If the ::new() works then nothing happens and you pointer `ptr`
// is valid and code continues to execute.
}
catch( … )
{
// You only have one catch block that catches everything.
// So if there are any statements that generate an exception this will catch
// the excetption and execute this code.
cout << "Too many elements" << endl;
}
// As you have caught all exceptions the code will continue from here.
// Either after the try block finishes successfully or
// After an exception has been handled by the catch block.
return 0;
}
Try-catch blocks are used to trap errors in the code.
At the most basic level, errors occur because the program tries to execute an invalid instruction. That instruction (read: line of code) could be invalid for a number of reasons. In your specific instance, the instruction could be invalid if your program was not able to allocate 1,000,000,000 bytes of memory to story your ptr. The most common exception is trying to access a bad pointer, which is called a Null Pointer Exception, which occurs when you try to perform some action on an Object that either has not been created, or has been deleted (or got corrupt). You will learn to hate that exception.
Using catch(...) tells the program to execute the code inside the catch block if any error occurs inside the code within the try block. There you can handle your error and try to find someway to either fix the error condition or gracefully exit that module.
You can also catch specific errors, which you can find out more about here : http://www.cplusplus.com/doc/tutorial/exceptions/
If you already know C, try/catch achieves the same thing as setjmp/longjmp when used for error handling. Think of try as code for the if condition of setjmp and catch code for else of setjmp. This makes longjmp equivalent to throw in C++, which is used to throw an exception. In your example, probably, the new operator, which calls some memory allocation function internally, throws an exception on seeing a very large number as input by using the C++ throw operator.
void a()
{
.......
longjmp(buf,1); // <--- similar to throw
.......
}
if ( !setjmp(buf) ) // <--- similar to try
{
.......
a();
.......
}
else // <--- similar to catch
{
.......
}
try/catch is a bit more sophisticated than setjmp/longjmp, as for setjmp/longjmp you will need to declare variables which are modified in between setjmp/longjmp calls as volatile, which is not necessary for try/catch.
Can some please explain why this exception isn't caught.
try {
// This will cause an exception
char *p = 0;
char x = 0;
*p = x;
}
catch (...) {
int a = 0;
}
When I run the program it dies on the line *p = x. I would expect that the catch block would cause this exception to be ignored.
I'm using the Qt Creator (2.2) with Qt 4.7.2 compiling with Visual Studios 2008 on Windows 7 32 bit.
There is no C++ exception being thrown here. You are causing undefined behavior because *p = x derefences a pointer with a null pointer value.
An exception is only propogated when you, or code you call, executes a throw expression. Undefined behaviour is not usually catchable.
Structured exception handling __try and __catch will catch system faults, see:
http://msdn.microsoft.com/en-us/library/swezty51(v=vs.80).aspx
Dereferencing a NULL pointer is undefined behaviour. In general, this will trigger a processor trap, and an OS level error. This may then be mapped to a signal, such as SIGSEGV, or to an Access Violation error, or it may abort your program, or do anything else.
On Windows, it is mapped to a "structured exception", which is a different beast to a C++ exception. Depending on how you've got MSVC configured, you may be able to catch this with catch(...), but not always.
If you want that you need to write a pointer test:
template<typename T>
inline T* ptr_test(T* test)
{
if (test == NULL)
{ throw std::runtime_error("Null Exceception");
}
return test;
}
Then your code looks like this:
try
{
// This will cause an exception
char* p = 0;
char x = 0;
*ptr_test(p) = x; // This is what java does.
// Fortunately C++ assumes you are smart enough to use pointers correctly.
// Thus I do not need to pay for this test.
//
// But if you want to pay for the test please feel free.
}
catch (...)
{
int a = 0;
}
You need to use the /EHa compiler option to switch on the (Microsoft compiler specific) feature which will enable SEH (Structured Exception Handling) exceptions (which is what your null access triggers) to be catchable by catch(...).
Having said that, I wouldn't recommend using /EHa. Better to use the __try/__except extension or the SEH API directly and keep your handling of "structured" exceptions separate from handling of C++ exceptions. Why ? Because C++ exceptions are just another perfectly legitimate well defined control flow mechanism, but most things which trigger SEH exceptions are likely to indicate your software has entered the realm of undefined behaviour and really the only sensible thing to do is exit gracefully. Using /EHa leads to this vital difference becoming unnecessarily blurred.
It's not caught because its not an exception - nothing is throwing. You're accessing null/unallocated memory which causes a segmentation fault which is a signal from the operating system itself.
Signals can only be caught by signal handlers, exceptions will not help you with those.
Exceptions only really help in areas where something might call throw(), like a library throwing an exception when you cause a divide-by-zero with the parameters you provided it.
All you're doing right now is dereferencing a null pointer, it is not an exception.
If you want this code to catch something, you have to throw something first. Say, something like:
try {
// This will cause an exception
char *p = 0;
char x = 0;
if (p == 0) throw 1;
*p = x;
}
catch (...) {
int a = 0;
}
Obviously, the catch block in the above example will always be executed.