can anyone please tell me how to catch out of memory exception?
for ex.
try
{
while(true)
{
int i = new int;
}
}
catch( ? <--- what should be put here?)
{
//exception handling
}
and also this,
queue<int> q;
try
{
while(true)
{
q.push(10);
}
}
catch( ? <---- what should be put here?)
{
//error handling
}
Catch std::bad_alloc.
You will also need a strategy for handling the errors, since many of the things you'd like to do will require memory (even if it's only to display an error to the user before shutting down). One strategy is to allocate a block of memory at startup, and delete it in the exception handler before attempting to use more memory, so that there is some available to use.
As others have noted, what you want to catch is std::bad_alloc. You can also use catch(...) or catch(exception& ex) to catch any exception; the latter allows the exception data to be read and used in the exception handler.
Mark Ransom had already pointed out that when the program cannot allocate any more memory, even printing an error message may fail. Consider the following program:
#include <iostream>
using namespace std;
int main() {
unsigned long long i = 0;
try {
while(true) {
// Leaks memory on each iteration as there is no matching delete
int* a = new int;
i++;
}
} catch(bad_alloc& ex) {
cerr << sizeof(int) * i << " bytes: Out of memory!";
cin.get();
exit(1);
}
return 0; // Unreachable
}
(I strongly recommend that the program be compiled as 32-bit to avoid running the system out of memory on a 64-bit machine. 32-bit programs cannot allocate more than 4 GB of memory, or 2 GB by default on Windows.)
When the first bad_alloc gets thrown in the infinite while loop, control is passed to the catch block, but the program still fails with an unhandled exception. Why? Another bad_alloc is thrown inside the exception handler while trying to print to cerr. You can verify this by using a debugger: Set a breakpoint at the catch(bad_alloc& ex) line, run the program in the debugger, then step through each statement once you reach the breakpoint. A bad_alloc exception will be thrown in the cerr statement.
As such, to properly handle an out-of-memory scenario, you need to set aside some memory so that you can print an error message before exiting. Otherwise, the program will just crash on an unhandled exception while trying to print the error message. To do so, you can allocate a block of memory that is deallocated in the exception handler, as Mark Ransom suggested:
// Reserve 16K of memory that can be deleted just in case we run out of memory
char* _emergencyMemory = new char[16384];
// ...
try {
// ...
} catch(bad_alloc& ex) {
// Delete the reserved memory so we can print an error message before exiting
delete[] _emergencyMemory;
cerr << sizeof(int) * i << " bytes: Out of memory!";
cin.get();
exit(1);
}
//...
catch (std::bad_alloc& ba){
cerr << "bad_alloc caught: " << ba.what() << endl;
}
As a note you should read bdonlan's comment. The call to cerr may very well fail. Mark Ransom's suggestion in his answer is a good strategy to mitigate this issue.
You should catch an object of type std::bad_alloc.
Alternatively, you can also use a nothrow verison of new as:
int *pi = new (nothrow) int[N];
if(pi == NULL)
{
std::cout << "Could not allocate memory" << std::endl;
}
When you use this, no exception is thrown if the new fails. Instead,it simply returns NULL which you check before proceeding further.
Related
For example, this code will throw Stack Overflow because of infinite recursion which will lead to the program crash. Is there a way to handle this exception and avoid the crash and move on to the next instruction execution?
#include <iostream>
#include <exception>
template <typename T>
T sum(T firstValue, T secondValue)
{
try{
return firstValue + secondValue;
}
catch(const std::exception &e)
{
std::cerr << "Caught exception: " << e.what() << '\n';
}
}
void causeStackOverflow() {
causeStackOverflow();
}
int main() {
std::cout << "Sum of 3 & 4 is: " << sum(3, 4) << '\n';
try {
causeStackOverflow();
}
catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << '\n'; // If anything can be done here so program can recover and next line can execute?
}
std::cout << "Sum of 1 & 2 is: " << sum(1, 2) << '\n';
return 0;
}
There must be some way which can be used here to do this. Another question would be if it should be done even if it's possible?
Is there any way which can predict with some probability that Stack Overflow is going to happen? So we can take some action to avoid that?
On Windows, with Microsoft Visual C++, you can handle a stack overflow using Structured Exception Handling (SEH) like this:
void causeStackOverflow() {
causeStackOverflow();
}
// Filter for the stack overflow exception.
// This function traps the stack overflow exception, but passes
// all other exceptions through.
int stack_overflow_exception_filter(int exception_code)
{
if (exception_code == EXCEPTION_STACK_OVERFLOW)
{
// Do not call _resetstkoflw here, because
// at this point, the stack isn't yet unwound.
// Instead, signal that the handler (the __except block)
// is to be executed.
return EXCEPTION_EXECUTE_HANDLER;
}
else
return EXCEPTION_CONTINUE_SEARCH;
}
int main() {
// Demonstrate handling a stack overflow 3 times.
for (int i = 0; i < 3; ++i) {
__try {
causeStackOverflow();
}
__except (stack_overflow_exception_filter(GetExceptionCode())) {
std::cout << "Handled!\n";
if (!_resetstkoflw()) {
// Failed to reset the stack. Emergency exit.
exit(-1);
}
}
}
}
Important: A stack overflow exception damages the guard page that will catch any subsequent stack overflow exceptions. You have to put these guard pages by calling _resetstkoflw if you want to be able to recover from another future stack overflow exception on that same thread. I strongly suggest reading the entire remarks section in the documentation.
The _resetstkoflw function recovers from a stack overflow condition, allowing a program to continue instead of failing with a fatal exception error. If the _resetstkoflw function isn't called, there are no guard pages after the previous exception. The next time that there's a stack overflow, there are no exceptions at all and the process terminates without warning.
...
You could refer to the MSDN document to debug stack overflow.
Use the !analyze command to check that we have indeed have a problem
with our loop.
dt _TEB can be used to display information.
It is difficult to catch exception because the OS will kill the process. For your reference: C++: Getting exception from stack overflow?.
I can't find a way to actually enable c++ exception handling in visual studio 2017. Maybe I am missing something trivial. I've searched a lot and found nothing that solves this simple issue.
Even this simple code does not act as expected:
#include <iostream>
//#include <exception>
int main(int argc, char *argv[])
{
try
{
int j = 0;
int i = 5 / j;
std::cout << "i value = " << i << "\n";
std::cout << "this line was actually reached\n";
}
catch (...)
//catch (std::exception e)
{
std::cout << "Exception caught!\n";
return -1;
}
std::cout << "Exception was NOT caught!\n";
std::cin.get();
}
When I execute this simple code the program crashes, like the exception is never caught, I tried also with std::exception variant, and i get the same result.
The division by zero is just an example, I could have wrote also something like this:
ExampleClass* pClassPointer = null;
pClassPointer->doSomething();
and expected that a nullpointer exception was automatically thrown and captured by the catch(...) clause.
Just as an information, I added the line:
std::cout << "i value = " << i << "\n";"
otherwise the compiler optimization would have skipped most of the code and the result (in RELEASE mode) was:
this line was actually reached
Exception was NOT caught!
In the properties page of the project, in the option "Enable C++ Exceptions" I have the value: "Yes (/EHsc)", so I think exceptions should be actually enabled.
Am I missing something?
Thank you in advance.
Andrea
---- Edit
I actually just found out that changing the option "Enable C++ Exceptions" with the value "Yes with SEH Exceptions (/EHa)" instead of "Yes (/EHsc)" allows to capture access violation and divide by zero errors in the catch(...) clause.
I've also found very useful information about this subject and whether or not is a good idea to catch those type of exceptions in the replies to this other thread:
Catching access violation exceptions?
In C++ you throw an exception, and, having done that, you can catch it. If you didn't throw it, you can't catch it.
Confusingly, there are many kinds of errors that are generically referred to as "exceptions". This is especially true in floating-point math, where anything that goes wrong is a "floating-point exception". It's the same word, but those exceptions are not C++ exceptions, and you cannot reliably catch them.
In general, when something goes wrong in your program you get undefined behavior, that is, the language definition does not tell you what the program does. So you're on your own: if your compiler documents what it does when a program divides an integer value by 0, then you can rely on that behavior. If not, don't count on anything.
#include <iostream>
int main(int argc, char *argv[])
{
try
{
int j = 0;
int i ;
if(j==0)
throw j; // you have throw some variable or atleast use throw for your
//catch to work
std::cout << "i value = " << j/5<< "\n";
std::cout << "this line was actually reached\n";
}
catch (int e) /*catch will work only if the data type of argument matches with the thrown variable's data type if it does not then the compiler's default catch will run*/
{
std::cout << "Exception caught!\n";
return -1;
}
std::cout << "Exception was NOT caught!\n";
std::cin.get();
}
if u still have any questions ask in comments!
I have been learning c++ recently and while working on exceptions, I came across something that confuses me. I threw a string exception and added multiple catch blocks to see how it works, and for some reason, the string exception is being caught in the int catch block. This is puzzling me and I cant see to find reasons why it would do it.
FYI, I am using GCC v 5.3.0
So, I was expecting the following message on the console.
String exception occurred: Something else went wrong
But instead, I got the following message.
Int exception occurred: 14947880
So I tried switching the order of the catch blocks and placed the string catch block on the top, and I got the string exception message. Could somebody please explain a reason why this is happening? It seems whatever catch block is in the top is being caught first.
I don't think this is the correct behavior and that the string exception block should be executed, but if I am wrong, please correct me. Thanks for taking time to look at this.
#include <iostream>
using namespace std;
void MightGoWrong()
{
bool error = true;
if (error)
{
throw string("Something else went wrong");
}
}
/**
* Output on console: Int exception occurred: 14947880
*/
int main() {
try
{
MightGoWrong();
}
// If string or char pointer catch block goes to top, that block will execute
catch (int e)
{
cout << "Int exception occurred: " << e << endl;
}
catch (string &e)
{
cout << "String exception occurred: " << e << endl;
}
catch (char const * e)
{
cout << "Char exception occurred: " << e << endl;
}
return 0;
}
Hi I am very new to C++ programming, and I am really hard to understand the code below in which they have used catch. So I want to know why do they use catch in this code. Thanks in advance
#include <iostream>
#include <exception>
using namespace std;
int main ()
{
try
{
int* myarray = new int[1000];
cout << "allocated";
}
catch (exception& e)
{
cout << "Standard exception: " << e.what() << endl;
}
return 0;
}
The operator new may throw an exception in case it cannot allocate the required space.
From the link above:
throwing (1) void* operator new (std::size_t size) throw (std::bad_alloc);
Throws bad_alloc if it fails to allocate storage. Otherwise, it throws
no exceptions (no-throw guarantee).
The statements in catch will be executed when one of the statements in the try block throws an exception. This tutorial link will helps a ton: http://www.cplusplus.com/doc/tutorial/exceptions/
try and catch come inside exception handling in C++
try
{
int* myarray = new int[1000];
cout << "allocated";
}
catch (exception& e)
{
cout << "Standard exception: " << e.what() << endl;
}
in this case first it wil check the memory allocation using try block and if it fail to allocate the memory then using catch it will throw exception,that memory could not be allocated
Is there some way to catch exceptions which are otherwise unhandled (including those thrown outside the catch block)?
I'm not really concerned about all the normal cleanup stuff done with exceptions, just that I can catch it, write it to log/notify the user and exit the program, since the exceptions in these casese are generaly fatal, unrecoverable errors.
something like:
global_catch()
{
MessageBox(NULL,L"Fatal Error", L"A fatal error has occured. Sorry for any inconvience", MB_ICONERROR);
exit(-1);
}
global_catch(Exception *except)
{
MessageBox(NULL,L"Fatal Error", except->ToString(), MB_ICONERROR);
exit(-1);
}
This can be used to catch unexpected exceptions.
catch (...)
{
std::cout << "OMG! an unexpected exception has been caught" << std::endl;
}
Without a try catch block, I don't think you can catch exceptions, so structure your program so the exception thowing code is under the control of a try/catch.
Check out std::set_terminate()
Edit: Here's a full-fledged example with exception matching:
#include <iostream>
#include <exception>
#include <stdexcept>
struct FooException: std::runtime_error {
FooException(const std::string& what): std::runtime_error(what) {}
};
int main() {
std::set_terminate([]() {
try {
std::rethrow_exception(std::current_exception());
} catch (const FooException& e) {
std::cerr << "Unhandled FooException: " << e.what() << std::endl;
} catch (const std::exception& e) {
std::cerr << "Unhandled exception: " << e.what() << std::endl;
} catch (...) {
std::cerr << "Unhandled exception of unknown type" << std::endl;
}
std::abort();
});
throw FooException("Bad things have happened.");
// throw std::runtime_error("Bad things have happened.");
// throw 9001;
}
You can use SetUnhandledExceptionFilter on Windows, which will catch all unhandled SEH exceptions.
Generally this will be sufficient for all your problems as IIRC all the C++ exceptions are implemented as SEH.
Without any catch block, you won't catch any exceptions. You can have a catch(...) block in your main() (and its equivalent in each additional thread). In this catch block you can recover the exception details and you can do something about them, like logging and exit.
However, there are also downside about a general catch(...) block: the system finds that the exception has been handled by you, so it does not give any more help. On Unix/Linux, this help would constitute creating a CORE file, which you could load into the debugger and see the original location of the unexcepted exception. If you are handling it with catch(...) this information would be already lost.
On Windows, there are no CORE files, so I would suggest to have the catch(...) block. From that block, you would typically call a function to resurrect the actual exception:
std::string ResurrectException()
try {
throw;
} catch (const std::exception& e) {
return e.what();
} catch (your_custom_exception_type& e) {
return e.ToString();
} catch(...) {
return "Ünknown exception!";
}
}
int main() {
try {
// your code here
} catch(...) {
std::string message = ResurrectException();
std::cerr << "Fatal exception: " << message << "\n";
}
}
Update: This covers c++98 only.
From More Effective C++ by Meyers (pg 76), you could define a function that gets called when a function generates an exception that is not defined by its exception specification.
void convertUnexpected()
{
// You could redefine the exception here into a known exception
// throw UnexpectedException();
// ... or I suppose you could log an error and exit.
}
In your application register the function:
std::set_unexpected( convertUnexpected );
Your function convertUnexpected() will get called if a function generates an exception that is not defined by its exception specification... which means this only works if you are using exception specifications. ;(
Provided that C++11 is available, this approach may be used (see example from: http://en.cppreference.com/w/cpp/error/rethrow_exception):
#include <iostream>
#include <exception>
void onterminate() {
try {
auto unknown = std::current_exception();
if (unknown) {
std::rethrow_exception(unknown);
} else {
std::cerr << "normal termination" << std::endl;
}
} catch (const std::exception& e) { // for proper `std::` exceptions
std::cerr << "unexpected exception: " << e.what() << std::endl;
} catch (...) { // last resort for things like `throw 1;`
std::cerr << "unknown exception" << std::endl;
}
}
int main () {
std::set_terminate(onterminate); // set custom terminate handler
// code which may throw...
return 0;
}
This approach also allows you to customize console output for unhandled exceptions: to have something like this
unexpected exception: wrong input parameters
Aborted
instead of this:
terminate called after throwing an instance of 'std::logic_error'
what(): wrong input parameters
Aborted
This is what I always do in main()
int main()
{
try
{
// Do Work
}
catch(std::exception const& e)
{
Log(e.what());
// If you are feeling mad (not in main) you could rethrow!
}
catch(...)
{
Log("UNKNOWN EXCEPTION");
// If you are feeling mad (not in main) you could rethrow!
}
}
Use catch (...) in all of your exception barriers (not just the main thread). I suggest that you always rethrow (...) and redirect standard output/error to the log file, as you can't do meaningful RTTI on (...). OTOH, compiler like GCC will output a fairly detailed description about the unhandled exception: the type, the value of what() etc.