Thread: memory leak detected when throwing exception

  1. #1
    Registered User
    Join Date
    Sep 2015
    Location
    Italy
    Posts
    38

    memory leak detected when throwing exception

    Hi,
    I'm trying to throw an exception without a memory leak happens.
    Googling I found this FAQ:
    https://isocpp.org/wiki/faq/exceptio...not-exceptions
    where I read: "Throwing an exception will not cure memory corruption and may lead to further corruption of important user data."
    Does it mean that throwing without catching always cause memory leakage? Since the exception object resides on the space managed by compilers does it depend on the compiler?
    Code:
    Code:
    #include <iostream>
    #include <stdexcept>
    
    void exercise()
    {
            std::exception ex;
            throw ex;       // memory leak
    }
    
    int main()
    {
            exercise();
            try { }
            catch(...)
            {
                    return EXIT_SUCCESS;
            }
    }
    memory leak detected when throwing exception-leak1-jpeg
    Thanks for any answer, best regards

  2. #2
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    You have a throw without a catch since you're not calling the function that throws within a try block.
    Code:
    #include <iostream>
     
    void exercise() {
        throw 1;    // you can throw any object, even an int
    }
     
    int main() {
        try {
            exercise();    // call the function within the try block
        }
        catch (...) {
            std::cout << "exception caught\n";     // handle the error here
        }
    
        return 0;
    }

  3. #3
    Registered User
    Join Date
    Sep 2015
    Location
    Italy
    Posts
    38
    Thanks for your answer, but memory leak happens the same if not catch:
    Code:
    #include <iostream>
    
    void exercise()
    {
            throw 1;        // memory leak
    }
    
    int main()
    {
            try {
                    exercise();
            }
            catch(char)
            {
                    std::cout << "char" << std::endl;
                    return EXIT_SUCCESS;
            }
    /*      catch(...)
            {
                    std::cout << "int" << std::endl;
                    return EXIT_SUCCESS;
            }*/
    }
    a catch all clause is it a mandatory in order to avoid memory leak when an exception is thrown? In other word should I expect memory leakage if terminate is called during stack unwinding?
    TIA

  4. #4
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    I'm not sure I'd call it a memory leak if your program is aborting. The OS will clean everything up. Are you under the impression that the memory is somehow "gone" until the next reboot? That's not the case on most (all?) "hosted" systems.

    Maybe you shouldn't be exiting the program (the return statements) inside the catch clauses. I'm not sure about that.

    However, I'm no expert on this so let's await some more experienced opinions.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The OS will generally clean up the mess your program leaves, yes, so you shouldn't worry about that. What you should worry about is destructors not being called. Since destructors are integral to the RAII programming paradigm, it considered bad practice to terminate without calling destructors. Hence, catch that exception!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by frank67 View Post
    Hi,
    I'm trying to throw an exception without a memory leak happens.
    Googling I found this FAQ:
    https://isocpp.org/wiki/faq/exceptio...not-exceptions
    where I read: "Throwing an exception will not cure memory corruption and may lead to further corruption of important user data."
    Does it mean that throwing without catching always cause memory leakage? Since the exception object resides on the space managed by compilers does it depend on the compiler?s
    No that's not what advice is saying at all. It says that when an invariant of your component is violated, an assertion that calls std::exit or std::terminate immediately is more suitable than throwing an exception. This is primarily a stylistic suggestion. The quoted portion is true in general, but depending on what a particular application does with an exception, may not apply. Nevertheless, it is good advice.

    For example, a function discovers that memory is corrupted. It then throws. In unwinding the stack, the application saves the corrupted memory to disk before closing the application. Now instead of just having memory corruption, you have a corrupt file, aka further corruption of user data, in part because you chose to use an exception instead of an assertion.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  7. #7
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    Quote Originally Posted by King Mir View Post
    No that's not what advice is saying at all. It says that when an invariant of your component is violated, an assertion that calls std::exit or std::terminate immediately is more suitable than throwing an exception. This is primarily a stylistic suggestion. The quoted portion is true in general, but depending on what a particular application does with an exception, may not apply. Nevertheless, it is good advice.
    The linked advice incorrectly assumes that coding errors == memory corruptions. In C++ coding errors are very often memory corruptions, but there are also other cases.

    Whether it is a good advice to use assertions for any programming errors or not, strongly depends on the context. Actually, it depends on the context so strongly that saying it is a good advice (implying a rule of thumb) is like saying that it is generally better to use language X over language Y. I cannot imagine a large system running 24/7 crashing only because one of its subcomponents failed due to one of its more or less important invariants (note: it does not have necessarily to be a memory corruption). In managed languages the rule is completely reverse - prefer exceptions over assertions unless you really have a good reason (e.g.: performance critical code). Exceptions are used there for runtime errors as well as for programming errors. Exceptions have many advantages over assertions, e.g.: process not terminating immediately, other resources being released, additional information being logged, ability to continue execution of the other tasks, etc. Also, assertions are hard or sometimes even impossible to write unit tests for (it depends on the toolset used, of course).

    Having said that, I would certainly not make it a "good advice" for anything other than memory invariants.

  8. #8
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by kmdv View Post
    The linked advice incorrectly assumes that coding errors == memory corruptions. In C++ coding errors are very often memory corruptions, but there are also other cases.

    Whether it is a good advice to use assertions for any programming errors or not, strongly depends on the context. Actually, it depends on the context so strongly that saying it is a good advice (implying a rule of thumb) is like saying that it is generally better to use language X over language Y. I cannot imagine a large system running 24/7 crashing only because one of its subcomponents failed due to one of its more or less important invariants (note: it does not have necessarily to be a memory corruption). In managed languages the rule is completely reverse - prefer exceptions over assertions unless you really have a good reason (e.g.: performance critical code). Exceptions are used there for runtime errors as well as for programming errors. Exceptions have many advantages over assertions, e.g.: process not terminating immediately, other resources being released, additional information being logged, ability to continue execution of the other tasks, etc. Also, assertions are hard or sometimes even impossible to write unit tests for (it depends on the toolset used, of course).

    Having said that, I would certainly not make it a "good advice" for anything other than memory invariants.
    The link does not make that assumption, it merely justifies a general rule with a specific case. It's style advice.

    Although in a particular project it may make sense to use exceptions for invariants, I consider the advice sound. As you say, C++ is not a managed language.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Throwing an exception in int main()
    By Programmer_P in forum C++ Programming
    Replies: 10
    Last Post: 04-04-2011, 01:06 PM
  2. Problem throwing exception from destructor (GCC 3.4.5)
    By Sebastiani in forum C++ Programming
    Replies: 12
    Last Post: 06-13-2010, 05:46 PM
  3. CRecordset::Open() is throwing an exception
    By cpjust in forum Windows Programming
    Replies: 1
    Last Post: 02-13-2008, 12:15 PM
  4. help, throwing exception from constructor
    By terracota in forum C++ Programming
    Replies: 5
    Last Post: 07-02-2004, 05:44 PM
  5. Deconstructor throwing exception
    By subdene in forum C++ Programming
    Replies: 13
    Last Post: 06-26-2004, 03:52 AM