I have a two Database class objects allocated on Stack. I inherit this database class in my personal defined class. Now Database class has a function named "Close()" which throws an exception if closing that instance of database fails. Now for client perspective i don't want Client to call close() everytime to close the connection, rather i want to declare a vitrual Desctuctor in Database class which will automatically close the connection when object goes out of scope.
Now problem i am facing is, if i create two DB objects, and now try to delete both and if close succedds for both it's fine, but if close fails for first object it throws an exception, and now second is still allocated (if dynamically allocated member objects), which results in memory leak. How to handle this situation.
you don't throw exception from the destructor what-so-ever!
See : http://www.stroustrup.com/bs_faq2.html#ctor-exceptions
Bjarne quote (can you throw exception from a d.tor):
Not really: You can throw an exception in a destructor, but that exception must not leave the destructor; if a destructor exits by a throw, all kinds of bad things are likely to happen because the basic rules of the standard library and the language itself will be violated. Don't do it.
You might not want to allocate any DB object on the stack anyway, a safe, reusable way is to use Connection Pool :
https://en.wikipedia.org/wiki/Object_pool_pattern
like this, the destruction of each conenction object iswhen the program exist, where you can handle the closing as integral part of the pool, and not in a spread way in some random functions
You probably should have a class for holding one database connection, and another class holding two instances of the first. Since I figure the creation of a database could fail as well, having each connection in its own class (with its own destructor) will handle partial construction / destruction quite nicely.
Besides, if a destructor throws, there is very little you can do (aside from logging the condition). Your application is doomed.
Do not throw exceptions from destructors, bad things happens, use a shutdown() method and call it ouside of destructor. Most C++ stuff is cleaned in destructors, if you throw from within a destructor you literally stop cleaning up things and you would end up having a C++ program in undefined state:
class Database{
std::vector<int> v;
connection c;
public:
~Database(){
c.close(); //ouch throws v don't get deallocated. (neither c)
}
};
may be changed to:
class Database{
std::vector<int> v;
connection c;
public:
~Database(){
// v deallocated here
}
void shutdown(){
c.close();
}
};
main.cpp
int main(){
Database d;
d.shutdown(); //even if d throws, d destructor will be called.
//and as consequence of d destructor also c & v
//destructors are called.
return 0;
}
since you have 2 databases
int main(){
Database d1,d2;
try{
d1.shutdown();
}catch( /** correct exception type*/){
//error handling for 1
}
try{
d2.shutdown();
}catch( /** correct exception type*/){
//error handling for 2
}
//both destructors called
return 0;
}
Chances are that if close fails, there is not good recovery path anyway, you are best off logging the error and then carrying on as if it succeeded. So I would suggest you call close in a try block in you destructor and just logging the error in the corresponding catch block. The destructor can then complete normally.
As #David mentions above, destuctors should never leak exceptions, this is because destructors are called when an exception happens and an exception in an exception causes a crash.
Exceptions should never be thrown in destructor call.
You should not call anything that can cause them there, otherwise, you're crashing your class safety.
You should add a function that checks if database object can be "closed", not an exception. If you imagine that you just can't call function in destructor that may throw exception, you will find solution.
My choice is to do not use destructors to destroy associated objects, if there is a chance that this must not be allowed.
Destructors are intended to free only internal object resources only. You can create a something like resource manager that will store pointers to all objects you need to control. These may be shared pointers. And let this class make your behavior and not objects theirself.
Related
In the following code, I use a wrapper object to temporarily store some stuff from a db in memory. My question is simple:
Can I be sure that the destructor is called? I am particularly worried about cases where
a) testCondition is true and the function returns early from an inner scope of the scope in which tempObj was constructed
b) some runtime error occurs during the execution of this function (which is caught at a higher level)
(As a side question: is this a good way to temporarily store some data? In my application, someFunc() is a save/export function of the current db.)
class TempStore
{
public:
TempStore() {/* delete some stuff from a db and store this in memory*/}
~TempStore() {/* write this stuff back into the db*/}
};
void someFunc(bool testCondition)
{
TempStore tempObj = TempStore();
// some code
if (testCondition)
return; //early return
// some more code
}
The destructor of an automatic object will be called when the program leaves the object's scope. This includes returning from the function (early or otherwise), and leaving via an exception - as long as the exception is handled. In the case of an exception, it's called during stack unwinding before the exception is handled.
It might not be called in some cases, including:
leaving via a call to longjmp; this gives undefined behaviour;
leaving via an exception that's not handled; it's unspecified whether the stack is unwound.
terminating the program (e.g. calling exit, or raising a signal that causes termination).
The destructor will be called unless the program blows up due to a seg fault or a power outage or whatever. Simply returning early from a function or throwing an exception is not enough to stop the destructor running.
This design is a bit flawed though, since writing to a database is an operation that could fail, and throwing an exception from a destructor is a pretty bad idea.
Yes, destructor will be called. Every object, created on stack will be correctly destroyed if you early return. If exception is thrown, destructor will be called after program execution arrived to the catch block.
Is it a good technique to perform important/critical tasks of an object in the destructor?
Such as:
class MyObject{
~MyObject() {
Execute();
}
void Execute() {...}
};
Destructors are meant to be a way to automatically clean up resources held by an object when it goes out-of- scope. Nothing else should be done in destructor. But the clean up may involve critical or complex processing. Also make sure exception does not leave your destructor. That will lead to terminate your program unexpectedly if the destrcutor was originally called because of stack unwinding due to another exception.
It is good practice to provide public interface for critical clean-up/resource management, so that client code can call it and handle if any exception arises. You can check if the clean up process is done in the destructor, if not perform it, but swallow any exception thrown.
To summarize, it is NOT a good practice to perform anything at all (whether critical or not) other than resource clean up in destructor.
Generally the answer is NO. E.g. if the program crashes, destructor won't be called. There're other circumstances when dtor isn't called. Destructor is dedicated method for clean up. Class users expect such behavior.
I have a class that distributes work given by the user to several threads. Something like (simplified):
class MT {
public:
MT();
void work1(/*args*/);
void work2(/*args*/);
void work3(/*args*/);
//waits until all threads complete, returns whether the work has been completed
//successfully, throws any exceptions that have been raised in the threads.
bool is_ok();
~MT();
private:
// thread pool
}
The user uses the class as follows:
void foo()
{
MT mt;
mt.work1(/*userdata*/);
mt.work2(/*userdata*/);
mt.work1(/*userdata*/);
status = mt.is_ok();
if (status) {
mt.work3(/*userdata*/);
//...
}
//...
}
The class is never part of some object, always stored on the stack.
The Problem
I want to somehow emit any exceptions that have been raised while doing work in other threads. Unfortunately, I know whether a thread has successfully completed only after joining it. Thus, I must choose between the following two alternatives:
Join the threads in the destructor of MT and throw exceptions that arose while doing work, if any. If more than one exception has been thrown, pick the one that came from the earliest task. If the destructor is called doing stack unwinding (we can check this using std::uncaught_exception, swallow any exceptions to prevent terminate().
Instruct the user to always call is_ok before the destructor.
I think the first option is cleaner, since the user is not required to call anything. However, throwing from destructor is usually very strongly discouraged. The presented arguments are:
Throwing from destructors is dangerous, because this might happed during stack unwinding and lead to terminate().
Even if the above is addressed, throwing or not throwing depending on whether stack is being unwound is a substantial change of behavior and should be discouraged.
Exceptions signify that a postcondition have not been met. The postcondition of a destructor is resource cleanup, this must be possible in any circumstances.
Somehow I am inclined to think that the above arguments don't apply here:
I handle the stack unwinding problem properly
Due to the usage pattern, any exceptions that exit from foo means that work has been failed. Throwing or not throwing in the destructor is not a substantial change of behavior.
The postconditions of the destructor are not only resource cleanup, but also that the work has been completed successfully. Thus an exception should be appropriate.
Questions
Do you think throwing from destructor is appropriate in this case?
No, don't throw from the destructor. Call is_ok, catch and ignore. Same as close() for streams.
The user can call is_ok if they want to be sure that the work has been completed, and it will throw an exception on failure.
In practice this is rarely inconvenient. It will be if the user writes a function with multiple return points, but (unfortunately) that's a problem they just have to deal with because C++ doesn't provide a means for you to do it for them. If you think this is anti-social, well, look at what happens if you destroy a std::thread in C++11 without first either joining it or detaching it. You're beating that :-)
So, user calls is_ok on all non-error exit paths. User doesn't bother calling it when there's already an exception, because they can't deal with another one anyway. Again, this is the same as close() for streams: if you want to see errors from writing your buffered stream then you just have to close or flush explicitly.
Even if the above is addressed, throwing or not throwing depending on
whether stack is being unwound is a substantial change of behavior and
should be discouraged.
It's also not possible to do correctly, at least in C++03. I don't know whether C++11 changes anything in this respect, but std::uncaught_exception does not tell you what you need to know, as Herb Sutter explains.
From your link to cppreference.com:
Any exception thrown while std::uncaught_exception() == true calls std::terminate.
I'm pretty sure this is false. terminate is called if an exception escapes a destructor that is called as part of stack unwinding, but it isn't called just because a destructor throws and catches an exception during unwinding.
If the caller thinks they can do something useful with an exception thrown in a destructor, then they can write a helper class that calls is_ok in its destructor, and put that over your object. If you think there's something useful that your class can do with the same exception then you can do something other than merely ignore it in your destructor, but you still shouldn't allow it to leave the destructor.
I've got this constructor which throws an exception
GenericSocket::GenericSocket(const string& hostname,
const string& servname):
_hostname(hostname),
_servname(servname)
{
initHints();
int rv;
if((rv = getaddrinfo(_hostname.c_str(),
_servname.c_str(),
&_hints,
&_servinfo)) != 0) {
throw GenericSocketException();
}
}
initHints() does a memset of _hints and sets some variables.
I test it with the google test framework like this:
TEST(CreateObject2, getaddrinfoException)
{
mgs_addrinfo_return = 1;
ASSERT_THROW(new GenericSocket("testhost", "4242"), GenericSocketException);
}
The test fails with a core dump:
[ RUN ] CreateObject2.getaddrinfoException
socket creation failed
terminate called after throwing an instance of 'common::GenericSocketException'
what(): Socket creation failed
[1] 43360 abort (core dumped) ./bin/test_common
Besides the fact that I dont know exactly what goes wrong, I suspect some uninitialised object gets deleted(?), a lot seems to happen under the hood, so I started to wonder if it is good practice to throw an exception in a constructor. Is it maybe better to put this functionality in another function which I can call after the creation of the object, and handle the exception afterwards?
IMHO, throwing an exception in a constructor is the best way to handle a situation like this - do you really want a usable object if there is no socket? it doesn't make sense to me. If it's failing to resolve that address, there's a reason for that and that is worthy of an exception (as long as you handle it correctly!)
In your particular case, you should test the return value and make the exception more useful... (for example, HostNotFound - which I'd guess is the case here)
Yes it is. You actually have no choice: constructors have no return values.
But take care of exception safety. See http://www.drdobbs.com/184403429 for instance, or google "strong exception guarantee". Indeed, an object whose constructor has thrown will not be destructed (it has never existed) and must be left in a state which doesn't leak resources.
Of course, the only reasonable thing to do when you can't construct an object is to throw exception, otherwise you would end up with some zombie objects. And answering your other question, no, you can't destroy an object that wasn't created.
Yes, throwing an exception is the most direct way to report that the constructor encountered problems, since they do not return values.
Destructors, on the other hand, should not throw exceptions, since they will be called in the stack unwinding phase of exception handling, and throwing another exception at this point would result in an abort.
There are already at least two discussions about this on SO. On both throwing exceptions from constructors and two-phase initialization:
1) When is it right for a constructor to throw an exception?
2) Throwing exceptions from constructors
If you learn at construction that you won't be able to create a valid object then throwing an exception is arguably your best option. The user of the class is thus forbidden from carrying on in case of error, unless they can handle it. That's usually the correct behaviour of a program.
function()
{
// 1. acquire resources.
// 2. perform action.
// 3. release resources.
}
If you can't fulfil step one then the other steps are futile. That's what we use RAII for: we acquire all the resources we need first, somewhat analogous to the old C style of programming with respect to stack variables. With RAII if any of the resources fail to acquire -- via an exception in the constructor -- then all previously acquired resources will release automatically and the second step will never be attempted. All done behind the scenes, automatically, but this assumes you throw an exception in the constructor if you can't create the object. It also assumes the destructor will do the clean-up.
struct Connection {
Connection() {
if( ! connect() ) throw ConnectionError();
}
~Connection() { // may not throw under any circumstances
try { disconnect(); }
catch( ... ) { }
}
void send(const std::string& message);
// ...
private:
bool connect();
// ...
};
void post(const std::string& message)
{
// step one is easy for the user:
Connection c;
// step two is the bulk of the work:
c.send("HELO");
// step three is automatically done for the user.
}
I know that I shouldn't throw exceptions from a destructor.
If my destructor calls a function that can throw an exception, is it OK if I catch it in the destructor and don't throw it further? Or can it cause abort anyway and I shouldn't call such functions from a destructor at all?
Yes, that's legal. An exception must not escape from the destructor, but whatever happens inside the destructor, or in functions it calls, is up to you.
(Technically, an exception can escape from a destructor call as well. If that happens during stack unwinding because another exception was thrown, std::terminate is called. So it is well-defined by the standard, but it's a really bad idea.)
Yes.
Look at the std::fstream class in the standard library for an example.
close() could potentially throw an exception.
The destroctor can call close() but the destructor does not throw (it will swallow any exceptions).
The concept is that if the destructor calls any methods that can throw then these methods should be public. Thus if the user of your object wants to check for exceptions they can use the public methods and handle the exception. If they do not care about the exception then just let the destructor handle the problem.
Going back to the std::fstream example.
{
std::fstream text("Plop");
// Load Text.
// I don't care if the close fails.
// So let the destructor handle it and discard exceptions
}
{
// If this fails to write I should at least warn the user.
// So in this case I will explicitly try and close it.
try
{
std::ofstram password("/etc/password");
// Update the password file.
password.close();
}
catch(...)
{
Message.ShowDialog("You failed to update the Password File");
}
}
You can find some examples here: https://software.intel.com/sites/products/documentation/doclib/iss/2013/sa-ptr/sa-ptr_win_lin/GUID-D2983B74-74E9-4868-90E0-D65A80F8F69F.htm
If an exception leaves destructor during stack unwinding of another exception being propagated, then std::terminate() is called.
When no stack unwinding is in progress, an exception can leave destructor without std::terminate() getting called. However, for objects allocated on heap this will result in memory leak because "operator delete" will not be called for the object who throws exception out of its destructor. Surprisingly, the destructor of base class still gets called in this case: What happens to base class destructor if a derived class destructor throws an exception
If the exception is catched inside the destructor (so that the exception does not leave the destructor), then no problem even if stack unwinding of another exception is in progress. This case is described more deeply here: http://bin-login.name/ftp/pub/docs/programming_languages/cpp/cffective_cpp/MEC/MI11_FR.HTM
Simple answer, never allow an exception from a dtor!
The complicated answer. You only get really nailed if the exception escapes the dtor while another exception is active. The normal case for this is when you are already unwinding the stack from another exception and the object in question is destroyed. In that case if the exception escapes the dtor then std::terminate is called, note you can put in your own handler for std::terminate by calling std::set_terminate. The default implementation of std::terminate is to call abort.
To complicate things more, most functions that want to make any guarantee about their exception safety, mainly the basic guarantee or the strong guarantee, rely on the underlying types to themselves not throw in their dtor*
The real question is, what state would your program be in when this error occurs? How can you recover? Where should this recovery be handled? You need to look at your specific case and work these issues out. Sometimes it's just fine to catch the exception and ignore it. Other times you need to raise some red flags.
So the answer is: it allowed by C++ to throw an exception in a dtor, but you shouldn't ever allow it to escape.
*Here's a brief synopsis of the exception guarantees (here's a much longer article)
Recap: Briefly define the Abrahams exception safety guarantees (basic,
strong, and nothrow).
The basic guarantee is that failed
operations may alter program state,
but no leaks occur and affected
objects/modules are still destructible
and usable, in a consistent (but not
necessarily predictable) state.
The strong guarantee involves
transactional commit/rollback
semantics: failed operations guarantee
program state is unchanged with
respect to the objects operated upon.
This means no side effects that affect
the objects, including the validity or
contents of related helper objects
such as iterators pointing into
containers being manipulated.
The nothrow guarantee means that
failed operations will not happen. The
operation will not throw an exception.
You may find this page from C++ FAQ Lite to be informative. The basic answer is, "don't do it." Where exactly do you plan to catch this exception? Whatever you plan on doing when you catch that exception, just do it with a function call instead or something (e.g. log it or set a flag to warn the user or whatever). Throwing exceptions from the destructor runs the risk of causing your entire program to terminate.