Why we need RAII for exception safety problems - c++

unique_ptr<X> f()
{
unique_ptr<X> p(new X); // or {new X} but not = new X
// do something - maybe throw an exception
return p; // the ownership is transferred out of f()
}
When the exception throw-ed, why we care about the existence of Object X,
why we care about the memory it occupied?
The process will terminated soon after the handling of the exception,
and the memory will be released, why we care about this?

Because in most applications, the process won't be terminated immediately, and you don't want to leak memory. You might as well ask why you should care about memory leaks at all.

The process will terminated soon after the handling of the exception
Says who?
If all you will do in the presence of an exception is terminate, then yeah, you can ignore it. However, there are plenty of exceptions that you should catch. Making your code relatively bullet-proof to exceptional circumstances is not a bad thing.
And once you decide to actually start trying to catch exceptions rather than ignoring them, you need RAII.

Related

Using STL containers with exception handling in low memory situation

I am using STL containers in my code (being developed in C++ using Visual Studio 2010)
I have never used exception handling with STL containers before. Since STL containers throw bad_alloc exception, I plan to use like in sample code shown below. Let's assume function() gets called in low memory situation.
Now, I am not sure if it is full proof code OR do I need to do any additional cleanup activity.
class MyClass
{
std::vector<int>* integer_vector;
public:
MyClass()
{
std::string message;
message += "my message"; // bad_alloc could be thrown from here
integer_vector = new std::vector<int>; // bad_alloc could be thrown from here
}
};
void function()
{
try
{
MyClass* myclass_ptr;
myclass_ptr = new (std::nothrow) MyClass;
if (myclass_ptr==NULL)
{
// ANY CLEANUP NEEDED HERE ?
return;
}
std::map<int, char> myintcharmap; // bad_alloc could be thrown from here
}
catch(...)
{
// ANY CLEANUP NEEDED HERE ?
return;
}
}
Please can someone have a look and help.
You have two main potential leaks in the code you show. Both of which arguably stem from using raw pointers. You should prefer using std::unique_ptr (if you have C++11) or other similar "smart" pointers to indicate ownership, and for exception safety in general. Modern guidance is to avoid almost all usage of new or delete; when they cannot be avoided, they need to be paired. Note that your code has two calls to new but none to delete.
Inside function, the core problem is you could fully allocate data "owned" by myclass_ptr, cause an exception in later allocations, and then not be able to clean it up as myclass_ptr is no longer in scope.
Let's say you fixed that so it cleaned up the MyClass instance if an exception occurred after its creation. Your code would still leak because inside MyClass there's currently a similar problem with integer_vector. Although you could follow the rule of three and write a destructor to handle this case, it's probably easier to use a smart pointer here as well.
Exception handling is much bigger, much more opinionated topic. I'll leave it with the summary that it's typically bad to catch exceptions and squash them (usually that's only legit in an outer loop of a program that needs specific kinds of stability). It's also typically bad to catch exceptions in a scope so narrow that you don't know how to handle them. (For example, how would function decide whether to try again, give up, or use another approach? Its caller, or the caller further on up the chain, may have more information and be in a better place to handle this.)
In most cases you should not deal with bad_alloc exceptions. Your try/catch should be removed, as well as if (myclass_ptr==NULL).
Ask yourself : if the process memory is exhausted, what could I possibly do ? Best thing you can hope is to log something, clean up / free the system resources, and let the program terminates. This is the only right thing to do.
You can do this by setting the new_handler (with set_new_handler). It will be called by the new operator if memory allocation failed.
std::set_new_handler(my_handler); // do your cleanup in 'my_handler'

Does std::tr1::shared_ptr throw bad_alloc and a good idea to be in try/catch block?

I am actually making a simple C++ SFML game and I want to learn much more into C++ programming.
Now I am using shared_ptr to manage resources. I have some question about shared_ptrs when creating a new resource like:
shared_ptr< Resource > resource( new Resource( World::LEVEL ) );
According to boost shared_ptr< class Y>( Y * p ) throws bad_alloc.
I dunno if std::tr1 does the same. And I do not know if I should worry about putting shared_ptr inside a try/catch block to check if bad_alloc is thrown. Is this a good programming practice?
Per the C++ 2011 standard, §20.7.2.2.1 ¶6:
template<class Y> explicit shared_ptr(Y* p);
Throws: bad_alloc, or an
implementation-defined exception when a resource other than memory
could not be obtained.
You catch exceptions when you know how to handle them. If you're going to handle a out-of-memory exception and have code to do so, then by all means, put it in a try-catch. If you're not writing mission-critical code and don't expect to be operating on the edge of system memory constraints, it's likely not necessary. Note that pretty much every line of code you write can throw exceptions once your system is out of memory.
It's important to note that on modern hardware/operating systems, "out of memory" doesn't mean that you've exceeded the physical memory constraints - you can have only 128MiB of memory and not get an error even when you use 10 times that, and you can have 8GiB of physical memory and get that error when you've only used half that much. This refers to the memory space available to your application, which the OS will page to disk if necessary (and assuming available disk space).
shared_ptr needs to allocate the counter, so it can throw
bad_alloc. (IIRC, when it does so, it calls delete on the
pointer passed into it.)
Whether you need to catch it is another question; you almost
certainly don't need to catch it in the function which creates
the shared_ptr. It's just another failed allocation, and
should be caught (or not) whereever you handle failed
allocations.

Which kind of code is considered exception safe?

A code which handles the exceptions well is called an exception safe code? Is this correct?
From here: https://codereview.stackexchange.com/a/9759/11619
You use lock/unlock pairs for the mutex. This is not exception safe.
So I would create an object that will do the lock in the constructor
and unlock in the destructor then use this to lock your mutexs. This
will make your code more exception safe.
class MutexLocker
{
pthread_mutex_t& mutex;
MutextLocker(pthread_mutex_t& mutex)
: mutex(mutex)
{
pthread_mutex_lock(&mutex);
}
~MutexLocker()
{
pthread_mutex_unlock(&mutex);
}
};
In which way is the above shown code exception safe? I don't see any exception handling over there.
Or does exception safe code mean where we can "add" the exception handling? So, the above shown code can be made exception safe by adding exception handling, but it isn't now?
Exception Safety is not about handling exceptions, it is about guaranteeing a number of properties about the program even in the presence of exceptions.
You can usually speak about the exception safety level of a given method:
No Guarantee: this method is exception unsafe, that is no guarantee is made, at all.
Basic Exception Guarantee: in case of exception no resource is leaked and the classes involved are still usable (but their state is unspecified), that is no memory leak, no file handle leak, no mutex leak and the invariants of the instances involved are still verified.
Strong Exception Guarantee: in case of exception, all state is reversed to what it was prior to beginning. This is a transaction like semantic.
NoThrow Guarantee: this method does not throw, it always succeeds.
In general, the NoThrow Guarantee only applies to the simplest methods (ie .size() on a vector for example) and the Strong Exception Guarantee may be costly to implement (being able to revert the effect or operating on a copy of the state may not be cheap).
On the other hand, the Basic Exception Guarantee is just that: Basic. Without it, safely operating a program is just impossible, so this is the least guarantee that is acceptable. If you leak resources or leave classes in an unusable state, the program may not be able to operate further.
This is why there is such an emphasis on RAII whenever exceptions are mentionned. Because RAII guarantees automatic cleanup of resources (memory, mutexes, files) whatever the path execution (regular return or exception) it is particularly desirable. However, RAII itself is not sufficient.
Related: Herb Sutter's GotW entry about Exception Safety and Exception Specifications.
the MutexLocker destructor is always called, also when an exception was raised in the block where it was constructed.
that is what makes a construct using your MutexLocker exception safe.
You don't have to handle an exception to be exception safe. You just have to survive when an exception is thrown.
The MutexLocker helps you do this by unlocking the mutex when you leave the scope. It doesn't matter if you leave by a return statement or because an exception is thrown.
"Exception safe" is a fairly overloaded term, but I would use it to describe sections of code which can have exceptions thrown through them and still maintain certain invariants (such as - nothing changes, no resources are leaked, all objects keep a valid state).
As an example, your void * printHello (void* threadId) function is correct (in that it always matches pthread_mutex_lock (&demoMutex) with pthread_mutex_unlock (&demoMutex)), but if someone changed the section in the middle so that it could throw an exception (for example, by setting the throw flags on std::cout), then your code would then permanently lock demoMutex, with no hope for it ever being released. This would constitute a bug in your program. void * printHello (void* threadId) is said to be "exception unsafe" because of this way in which bugs can easily be introduced into your program by adding exception handling to seemingly unrelated parts.
Using a RAII class to manage resources a good way to go about writing exception safe code (and is the resource management style to use in C++), because it avoids the need for duplicate manual cleanup in catch(...) blocks, and it enforces the cleanup of resources by using the type system.
A code which handles the exceptions well is called an exception safe code?
Yes, but you do not say what well is. This is a good read on exception safety.
In which way is the above shown code exception safe?
That code is not exception safe in itself. That is meant to be used in a exception safe code. For example :
void bar()
{
throw std::runtime_error( "lala" );
}
void foo()
{
pthread_mutex_lock(&mutex);
bar();
// OPS! mutex not unlocked
pthread_mutex_unlock(&mutex);
}
This problem is solved by using the class that automatically unlock the exception. Next example has exception handling with strong guarantees :
void foo()
{
MutexLocker locker( mutex );
try {
bar();
} catch ( const std::runtime_error & )
{
// revert changes
}
}
The code you provided serves the purpose well. Simply because when execution leaves the block in which the MutexLocker object is defined, the object is destroyed and the mutex is released as per its destructor. This holds no matter the reason for the exit.
You don't have to code this class yourself though. The C++ standard specifies a class named lock_guard that does exactly that.
http://en.cppreference.com/w/cpp/thread/lock_guard

Any pitfalls with allocating exceptions on the heap?

Question says it all: Are there any pitfalls with allocating exceptions on the heap?
I am asking because allocating exceptions on the heap, in combination with the polymorphic exception idiom, solve the problem of transporting exceptions between threads (for the sake of discussion, assume that I can't use exception_ptr). Or at least I think it does...
Some of my thoughts:
The handler of the exception will have to catch the exception and know how to delete it. This can be solved by actually throwing an auto_ptr with the appropriate deleter.
Are there other ways to transport exceptions across threads?
Are there any pitfalls with allocating exceptions on the heap?
One obvious pitfall is that a heap allocation might fail.
Interestingly, when an exception is thrown it actually throws a copy of the exception object that is the argument of throw. When using gcc, it creates that copy in the heap but with a twist. If heap allocation fails it uses a static emergency buffer instead of heap:
extern "C" void *
__cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) throw()
{
void *ret;
thrown_size += sizeof (__cxa_refcounted_exception);
ret = malloc (thrown_size);
if (! ret)
{
__gnu_cxx::__scoped_lock sentry(emergency_mutex);
bitmask_type used = emergency_used;
unsigned int which = 0;
if (thrown_size > EMERGENCY_OBJ_SIZE)
goto failed;
while (used & 1)
{
used >>= 1;
if (++which >= EMERGENCY_OBJ_COUNT)
goto failed;
}
emergency_used |= (bitmask_type)1 << which;
ret = &emergency_buffer[which][0];
failed:;
if (!ret)
std::terminate ();
}
}
So, one possibility is to replicate this functionality to protect from heap allocation failures of your exceptions.
The handler of the exception will have to catch the exception and know how to delete it. This can be solved by actually throwing an auto_ptr with the appropriate deleter.
Not sure if using auto_ptr<> is a good idea. This is because copying auto_ptr<> destroys the original, so that after catching by value as in catch(std::auto_ptr<std::exception> e) a subsequent throw; with no argument to re-throw the original exception may throw a NULL auto_ptr<> because it was copied from (I didn't try that).
I would probably throw a plain pointer for this reason, like throw new my_exception(...) and catch it by value and manually delete it. Because manual memory management leaves a way to leak memory I would create a small library for transporting exceptions between threads and put such low level code in there, so that the rest of the code doesn't have to be concerned with memory management issues.
Another issue is that requiring a special syntax for throw, like throw new exception(...), may be a bit too intrusive, that is, there may be existing code or third party libraries that can't be changed that throw in a standard manner like throw exception(...). It may be a good idea just to stick to the standard throw syntax and catch all possible exception types (which must be known in advance, and as a fall-back just slice the exception and only copy a base class sub-object) in a top-level thread catch block, copy that exception and re-throw the copy in the other thread (probably on join or in the function that extracts the other's thread result, although the thread that throws may be stand-alone and yield no result at all, but that is a completely another issue and we assume we deal with some kind of worker thread with limited lifetime). This way the exception handler in the other thread can catch the exception in a standard way by reference or by value without having to deal with the heap. I would probably choose this path.
You may also take a look at Boost: Transporting of Exceptions Between Threads.
There are two evident one:
One - easy - is that doing throw new myexception risk to throw a bad_alloc (not bad_alloc*), hence catch exception* doesn't catch the eventual impossible to allocate exception. And throwing new(nothrow) myexception may throw ... a null pointer.
Another - more a design issue - is "who has to catch". If it is not yourself, consider a situation where your client, that may also be a client of somebody else, has - depending on who's throwing - to decide if delete or not. May result in a mess.
A typical way to solve the problem is throwing a static variable by reference (or address): doesn't need to be deleted and doesn't require to be copied when going down in the unrolled stack
If the reason you're throwing an exception is that there's a problem with the heap (out of memory or otherwise) allocating your exception on the heap will just cause more problems.
There is another catch when throwing std::auto_ptr<SomeException>, and also boost shared pointers: while runtime_error is derived from exception, auto_ptr<runtime_error> is not derived from auto_ptr<exception>.
As a result, a catch(auto_ptr<exception> &) won't catch an auto_ptr<runtime_error>.

Shall I place try...catch block in destructor, if I know my function won't throw exception

I know destructor shouldn't not throw exception.
http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.13
I have the following code :
~a()
{
cleanup();
}
// I do not expect exception being thrown in this function.
// If exception really happen, I know that it is something not recoverable.
void a::cleaup()
{
delete p;
}
In my static source code analysis, it complains that I shall call the cleanup function in this way :
~a()
{
try {
cleanup();
}
catch(...) {
// What to do? Print out some logging message?
}
}
// I do not expect exception being thrown in this function.
// If exception really happen, I know that it is something not recoverable.
void a::cleaup()
{
delete p;
}
I am not sure whether this is a good practice, to place try...catch block in destructor, whenever it calls functions. As :
(1) If cleanup function able to throw exception, I know something bad had happened. I prefer it to be fail-fast. That is, just let the whole system crash, and let the programmer debugs it.
(2) Overhead occur while entering and exiting try...catch block.
(3) The code look cumbersome, with a lot of try...catch block around classes' destructor.
I may miss out some other points, why try...catch block should be in place.
Thanks.
Since delete won't throw, neither will cleanup and as such there is no need to put the call in try-catch.
Since your static analysis tool is probably having a hard time figuring that out, perhaps you could help it out (it's only a guess though) by declaring cleanup as no-throw.
void cleanup() throw();
Maybe you can be more precise about your cleanup function. Does the cleanup() function throw an exception intentionally, if only in very rare circumstances? Then you should definitely handle the case in your destructor because, even if rare, exception-throwing is expected behavior of cleanup().
At the very least, your exception handling code could leave your program in a well-defined state that would allow you to end your program gracefully.
Or do you mean cleanup() may throw e.g. an OutOfMemoryException or another runtime exception that you never handle anywhere else? Then I would omit the exception handling in the destructor as well. In such unusual circumstances, your application could probably not run its error handling code anyway. You should do everything possible to make sure even such an exceptions gets reported or logged properly.
Edit:
Now that you have shown the implementation of cleanup, Neil has already answered your question. delete p must not throw, hence a::cleanup will not throw as long as p's destructor does not throw.
Surely the issue is really in the destructor of p. When, in cleanup(), you say
delete p;
delete itself cannot throw, therefore the exception must comne from p's destructor. It is in that destructor you need to worry about using a try block, not the one for a.
There's not usually any point in throwing an error due to memory allocation or deletion. It either works or not, and you can spend a ton of work handling silly errors without getting any benefit.
You might want to do this in specific cases but it's nor done much in practice and when there's question you usually want to use debugger or more full instrumentation.
Fundamentally, it is not safe to throw an exception whilst already handling an exception.
If your destructor is being called whilst the stack is unwinding, and another exception is thrown, then your thread can be terminated immediately on some systems such as Symbian; that your code was planning to catch the exception won't stop that termination - your code won't even be called. Your thread certainly will be terminated if your exception escapes the destructor.
So try {} catch(...) {} in a destructor is not portable and is certainly tricky.
The sound advice is never call code that could throw an exception in cleanup code such as destructors and any function that might be called from a destructor, such as 'cleanup()', 'close()' or 'release_something()'.
The original poster also queries the performance of try-catch. Early in the adoption of C++ exceptions, exception handling code was reasonably expensive; these days, your compiler almost certainly uses zero-cost exceptions, which means that an exception not thrown adds no runtime performance penalty to the code (but of course does slightly increase the binary size of the program).
I never use this, but exception safety purists will say that your cleanup() function may throw without you expecting it. So this pattern is a technique for extra safety.
However, a cleanup function should not throw in the first place. So I would put any exception handling inside cleanup(), not in the destructor itself.