Thread: Classes that can crash during initialization

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    88

    Classes that can crash during initialization

    Hi guys,

    I was wondering if you have a class instance crash your program during initialization, does everything the constructor has done up to that point come undone? I take it that all classes created are automatically destroyed, and the same with concrete types, but what about free-store objects? Are they automatically deleted? Could a call to abort() cause a memory leak (just in case the OS didn't clean up properly)?

  2. #2
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    It is my understanding that it depends on how the class has been implemented. If the class has pointer data members whose initialization/assignment was done through free-store objects defined outside the class, you will have a memory leak. You avoid this by defining a smart pointer structure for your class, for instance. You will also have a memory leak if the class implements free-store objects inside its definition, but incorrectly manages them.

    As I see it, destructors still get called on program crash. If the class manages its own pointers and its own free store objects, it will gracefully release any memory usage.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    > As I see it, destructors still get called on program crash.
    No, at least, if a constructor fails and you throw an exception your destructor is never called, so like you said it is better to use members that handle their own memory.

    And if a constructor fails and it isn't caught, that seems to be undefined behavior: it may crash or it might not, and there is still no guarantee the destructor is called.

    See also: http://www.parashift.com/c++-faq-lit....html#faq-17.2

  4. #4
    Registered User
    Join Date
    Oct 2005
    Posts
    88
    Thanks for the help. What about a situation like this though:
    Code:
    class PossibleLeaker {
        A *aptr;
        B b;
        C c;
    public:
        PossibleLeaker() {
            A *aptr = new A;
            b.init();
            c.init(); // just to make it obvious that the constructor isn't finished.
        }
        ~PossibleLeaker() {
            if( aptr ) delete aptr;
        }
    };
    Say the function 'b.init()' caused the program to terminate suddenly (in a way that couldn't be caught by PossibleLeaker's constructor). Would PossibleLeaker's destructor be called/the constructor's work be undone? I don't see how it could since the object isn't even constructed yet. Could that be a memory leak?

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    > Could that be a memory leak?
    I'd say it depends on how C's init() function works, and if C handles it's own possible construction problems. These kinds of things can snowball quickly, so if you at least fix Possible Leaker's class members, you greatly reduce the risk of having construction problems.

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> Would PossibleLeaker's destructor be called/the constructor's work be undone?
    No. Look at FAQ number 17.4 in citizen's link.

  7. #7
    Registered User
    Join Date
    Oct 2005
    Posts
    88
    Quote Originally Posted by citizen
    > Could that be a memory leak?
    I'd say it depends on how C's init() function works, and if C handles it's own possible construction problems. These kinds of things can snowball quickly, so if you at least fix Possible Leaker's class members, you greatly reduce the risk of having construction problems.
    Did you meant to write B instead of C or am I missing something? If b.init() terminates then will the constructor of PossibleLeaker not just fail before it reaches c.init()?

    Other than that, I think I'll just have to make do with using exceptions and report errors in a sort of global way rather than have each class handle its own (by reporting and terminating). It does seem like better style doing what you suggested, but it means I need to properly learn about exceptions before I can have my code working (C++'s learning curve may not be steep, but it doesn't seem to know where to end!).

  8. #8
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    > Did you meant to write B instead of C or am I missing something? If b.init() terminates then will the constructor of PossibleLeaker not just fail before it reaches c.init()?
    No, I read that wrong. In a way it's the comment's fault really.

    > C++'s learning curve may not be steep, but it doesn't seem to know where to endl;
    A good C++ book covers exceptions and what happens in detail, but learning exceptions is easy, just read a tutorial.

  9. #9
    Registered User
    Join Date
    Dec 2004
    Location
    UK
    Posts
    109
    I think this was discussed in detail in a guru of the week but I can't remember which.

    If I recall correctly it boiled down to having to catch all the possible exceptions in your constructor, cleaning up any allocated memory in the catch block and rethrowing an exception if need be.
    Last edited by sigfriedmcwild; 06-26-2006 at 04:01 PM.

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Or use RAII for all your member variables so that they will be cleaned up automatically if an exception is thrown from the constructor.

  11. #11
    Registered User
    Join Date
    Dec 2004
    Location
    UK
    Posts
    109
    Do you mean using smart pointers?
    As far as I know RAII (resource aquisition is initialisation) and smart pointers are not the same thing, they just work well together.

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Smart pointers are one example of the use of RAII. They would help in this situation because they use RAII. Note that "resource acquisition is initialization" doesn't accurately identify the true meaning of RAII. It is more about the fact that a resource will be cleaned up automatically when the object goes out of scope. In the case of dynamically allocated memory, a smart pointer will delete the raw pointer automatically if an exception is thrown without any extra code, so if your class contains only smart pointers then no catch is necessary in the constructor to delete that memory.

    The benefits of RAII in this situation are more broad than just dynamically allocated memory. For example, fstream uses RAII. If you open a file with an fstream in your constructor, and then later an exception is thrown inside that constructor, the file will be closed automatically.

  13. #13
    Registered User
    Join Date
    Dec 2004
    Location
    UK
    Posts
    109
    Fair enough.
    Although RAII does stand for resource aquisition is intialisation.

    I always understood the advantage of RAII to be in the object creation stage when the object would come into existance fully working without needing further processing (and avoiding aquisition of resources early on in the code, with the intialisation a long way down, leaving an object that was not quite usable around)
    Last edited by sigfriedmcwild; 06-26-2006 at 04:48 PM.

  14. #14
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Quote Originally Posted by sigfriedmcwild
    Although RAII does stand for resource aquisition is intialisation.
    It does, however Daved's point I believe was that the name alone doesn't tell the whole story.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  15. #15
    Registered User
    Join Date
    Dec 2004
    Location
    UK
    Posts
    109
    Well after Daved raised his point I went off and did some research.
    Indeed RAII doesn't tell the whole story, the idiom would be more aptly named "resource aquisition is initialisation, release is (erk I'm missing the right word here)"

    Anyway RAII is a great solution for the original poster's problem. (And I'm sure nobody will mind too much the sideline discussion abotu hte meaning of RAII)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can you Initialize all classes once with New?
    By peacerosetx in forum C++ Programming
    Replies: 12
    Last Post: 07-02-2008, 10:47 AM
  2. Derived classes and initialization lists
    By DominicTrix in forum C++ Programming
    Replies: 2
    Last Post: 09-05-2004, 05:15 PM
  3. Exporting VC++ classes for use with VB
    By Helix in forum Windows Programming
    Replies: 2
    Last Post: 12-29-2003, 05:38 PM
  4. Questions on Classes
    By Weng in forum C++ Programming
    Replies: 2
    Last Post: 11-18-2003, 06:49 AM
  5. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM