   Exceptions
  I'm currently reading Sebesta's book about programming languages, and in the chapter about C++ exceptions, he writesQuote:When an exception terminates a try construct, all stack-dynamic and heap-dynamic variables that were allocated by code executed in the try construct before the exception occured are deallocated.I was very suspicious about the heap-dynamic variables part, so I wrote the following program:#include <iostream>#include <string>using namespace std;class Foo{    string text;public:    Foo(string text): text(text)    {   cout << "construction of " << text << endl;    }    ~Foo()    {   cout << "destruction of " << text << endl;    }};int main(){    try    {   Foo a("stack variable");   Foo* b = new Foo("heap variable");   throw 42;    }    catch (int i)    {    }    cout << "end of main" << endl;}The output of the program isconstruction of stack variableconstruction of heap variabledestruction of stack variableend of mainDid I misunderstand Sebesta, or is he just wrong?Another question, how come not even a is destructed when I change main to this?int main(){    Foo a("stack variable");    Foo* b = new Foo("heap variable");    throw 42;    cout << "end of main" << endl;}construction of stack variableconstruction of heap variableThis application has requested the Runtime to terminate it in an unusual way.Please contact the application's support team for more information.Two other questions about exception safety:1. Am I right in assuming that the concept of exception safety doesn't apply to constructors? The purpose of a constructor is to ensure the object's invariants for the first time, but if an exception is thrown during construction, there is no way to guarantee the object is in a valid state, right?2. How do I make a member function exception safe that has to reallocate dynamic memory for two different member variables? My first attempt:class Bar{    size_t len;    char *a, *b;public:    Bar()    {   len = 100;   a = new char[len];   b = new char[len];    }    void bar(int newLen)    {   char *p = new char[newLen];   char *q = new char[newLen];   len = newLen;   delete[] a;   a = p;   delete[] b;   b = q;    }};bar will leak the memory pointed to by p if the second allocation fails, right? So how do I make bar exception safe?These aren't actual problems for me, I'm just curious ;-) Thanks for your time.   
  For every new you call, *you* must call delete.try    Foo* b = NULL;    {   Foo a("stack variable");   b = new Foo("heap variable");   throw 42;    }    catch (int i)    {    }    if (b) delete b;    // or    delete b;or    Foo* b = NULL;    {   Foo a("stack variable");   std::auto_ptr<Foo> b(new Foo("heap variable"));   // or   // boost::scoped_ptr<foo> b = new Foo("heap variable");   throw 42;    }    catch (int i)    {    }Quote:Another question, how come not even a is destructed when I change main to this?I'm not sure on standard right now. C++ does not provide default exception handler. So if you don't catch global exception, application will exit, since it doesn't know how to continue after exception was thrown.Quote:1. Am I right in assuming that the concept of exception safety doesn't apply to constructors? The purpose of a constructor is to ensure the object's invariants for the first time, but if an exception is thrown during construction, there is no way to guarantee the object is in a valid state, right?You can throw in constructor, in which case, the object will never be constructed. You cannot obtain an instance of an class whose constructor has thrown. This is the concept behind RAII.Quote:2. How do I make a member function exception safe that has to reallocate dynamic memory for two different member variables? My first attempt:void bar(int newLen)    {   char *np = NULL;   char *nq = NULL;   try {*np = new char[newLen];*nq = new char[newLen];// if we get to here, we can't throw anymore// if something did throw, we won't modify anything at allstd::swap(p,pp);std::swap(q,pq);len = newLen;   } catch (...) { // or perhaps just std::bad_alloc   }   // - if exception occured, delete new allocations   // - if it didn't, swap succeeded, and we delete old versions   delete[] np;   delete[] nq;    };  I'd recommend reading this article on auto_ptr.  There are other, more flexible smart pointers, but auto_ptr was created with exception safety in mind.  It's also part of the standard library which is handy.   ;  I think Sebesta made a mistake there. The memory for the pointer itself might be deallocated but not the pointee.For the other example, you just might not be seeing the destructor line because the output is buffered. Just as it is difficult to see the destructor of statically allocated objects run. Try this instead:int main(){    {   Foo a("stack variable");   Foo* b = new Foo("heap variable");   throw 42;   cout << "end of inner scope" << endl;    }    cout << "end of main" << endl;}As for question 1, the object is never completely constructed so there is no object to be in an invalid state. For writing exception safe code for question 2 I prefer using smart pointers instead of using try-catch blocks but you still need the construct-temporary-and-swap idiom (I am sure that is not the real name of the idiom). :)   ;Interesting read related to constructors and exceptions.   ;  The heap variables comment is either downright wrong or at best highly misleading.  And the only reason I allow the possiblity of "highly misleading" is because if you "new" a class, and the constructor for the class throws, then the memory allocated by new will be delete'd for you automatically.  However, once control returns to your program, then it's entirely up to you to manage the memory (hopefully by using a smart pointer).e.g.:#include <iostream>using namespace std;class Foo{public:    Foo() {cout << "Foo (throwing)" << endl; throw 0;}   ~Foo() {cout << "~Foo" << endl;}    void * operator new(size_t n)   {cout << "new" << endl; return ::operator new(n);}    void   operator delete(void* p) {cout << "delete" << endl; return ::operator delete(p);}};int main(){    try    {   new Foo();    }    catch(...)    {    }}Output is:newFoo (throwing)deleteNote that delete was called (and the destructor was not).Quote:Another question, how come not even a is destructed when I change main to this?When you have an unhandled exception a bunch of things happen, but assuming you don't do anything to disrupt the process eventually you end up calling abort(), which is not required to call destructors.   ;Quote:Original post by DevFredDid I misunderstand Sebesta, or is he just wrong?He is just wrong.Quote:Another question, how come not even a is destructed when I change main to this?The standard C++ language definition does not require the stack to be unwound (ie. destructors of objects in automatic storage, "stack object") when an exception is thrown but not caught.The standard says the default action when an exception is thrown is to call terminate(), which by default calls abort().  The default acton of abort() is to return control to the invoking environment without executing any further code in the application (including destructors, finalizers, or wind-down code, including the destructors of objects in static storage, "global objects").;Quote:Original post by BregmaQuote:Original post by DevFredDid I misunderstand Sebesta, or is he just wrong?He is just wrong.Well, that's error #39 on my list then :)   ;Quote:Original post by godechoauto_ptr was created with exception safety in mind.OK, so how about this code?void bar(int newLen){    auto_ptr<char> p(new char[newLen]);    auto_ptr<char> q(new char[newLen]);    len = newLen;    delete[] a;    a = p.release();    delete[] b;    b = q.release();};Quote:reallocate dynamic memoryWhat is this constraint on your code that means this is required (by which i mean explicit use of new/delete)? Personally in c++ i carry all memory and other resources around in either stl containers or 'smart' pointers to obtain exception safety and am done with it. you reallocate by just reassigning - ie my_a = shared_ptr< A>( new A).If you need to 'leak' the raw memory either for accessing c style interfaces or alternatively to ease syntax then you can do this as well. const char *cp std::string.c_str(); int *vp = &std::vector[ 0];A *ap = boost::shared_ptr< A>.get(); If you're being passed back a resource from an interface where you have a responsibility to manage that resource then you can assign it a smart pointer type with a default (memory) or custom deleter (other resource).  