Am I leaking?

This is a discussion on Am I leaking? within the C++ Programming forums, part of the General Programming Boards category; If I have the following: Code: try { var = new myclass(); } catch (std::exception& e) { std::cout << e.what() ...

  1. #1
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    398

    Am I leaking?

    If I have the following:
    Code:
    try
    {
        var = new myclass();
    }
    catch (std::exception& e)
    {
        std::cout << e.what() << std::endl;
        return -1;
    }
    Do I need to add "delete var" in the catch block? I would fire up valgrind if I had a working linux OS.

  2. #2
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    Nope. The exception, I'm assuming, occurs inside myclass(). If this is so, it will occur before the assignment -- var never gets a value. You have nothing to free.

    Now, internally, the class's constructor must make sure to deallocate anything that needs deallocation. Members inside the class will have their destructors called, but the class itself will not (if an exception occurs during the constructor.) Here's a test:

    Code:
    #include <iostream>
    #include <stdexcept>
    
    class B
    {
    public:
    	B() { std::cout << "B created!" << std::endl; }
    	~B() { std::cout << "B destroyed... :-(" << std::endl; }
    };
    
    class A
    {
    public:
    	A() { throw std::runtime_error("BOOM."); }
    	~A() { std::cout << "A destroyed." << std::endl; }
    private:
    	B m_b;
    };
    
    int main()
    {
    	A *a = NULL;
    
    	try
    	{
    		a = new A();
    	}
    	catch(std::exception &e)
    	{
    		std::cout << "e.what() = " << e.what() << std::endl;
    		std::cout << "a = " << a << std::endl;
    	}
    
    	return 0;
    }
    Last edited by Cactus_Hugger; 07-14-2009 at 08:43 PM.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    >> Do I need to add "delete var" in the catch block?

    If, however, you add any code after the call to new, then yes, you need to delete var inside the catch block (and make sure it is initialized to 0 before you call new so that if an exception occurs before that assignment the delete has no effect).

    A better solution is to use RAII. Which smart pointer is right for the job depends on how you are using the variable and how long you want it to live. In the simple example you showed, you could use auto_ptr from the standard library, but in such a simple example you probably don't need dynamic memory anyway.

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,288
    Don't forget to consider the case where it doesn't throw. Then you'll still need to do the manual cleanup otherwise you would leak. Thus it's better to use a smart pointer anyway.

    But really, you need to show more code. There are ways those exact lines of code could happen to not leak, even if there was no exception thrown.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Adding delete var; in the catch block couldn't hurt if var was set to NULL before the try block. That way if you add extra code in the try block later, you don't have to remember to add the delete, since it's already there.
    But smart pointers might be a better way to go anyways.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  6. #6
    Registered User
    Join Date
    Apr 2006
    Posts
    137
    In other languages like C# and Java there is a
    Code:
    try {
     Something
    } catch(Exception e){
    
    } finally {
     delete ....;
     file.close();
    }
    Unfortunately, C++ doesn't have that. So yes if you were to allocate memory and the program has an exception then the Operating System has to deallocate the memory I believe.
    ★ Inferno provides Programming Tutorials in a variety of languages. Join our Programming Forums. ★

  7. #7
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Unfortunately, C++ doesn't have that.
    But fortunately it has RAII:

    Code:
    try {
        file = std::ifstream(somefile);
        shared_ptr<X> xp(new X);
        ...
    } catch (std::exception& ) {
        ...
    }
    
    //look, no finally!
    It is good to know how to do manual memory management, but in practice you should rarely need to do it (unless you are implementing really low level classes). In particular, exceptions and naked pointers don't match well.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  8. #8
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,411
    Quote Originally Posted by execute View Post
    So yes if you were to allocate memory and the program has an exception then the Operating System has to deallocate the memory I believe.
    Nope!
    C++ has a very powerful alternative as just mentioned.
    It will take care of freeing the memory if an exception were to occur.

    There simply is no need for a finally keyword/functionality in C++.
    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.

  9. #9
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    398
    Thanks guys for your input. I need this kind of input because I have no idea of the capabilities of C++ and these kind of threads really help me. I think I would like to focus on RAII as my design pattern, so thank you for the tips.

  10. #10
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Elysia View Post
    There simply is no need for a finally keyword/functionality in C++.
    There may not be a need, but it would certainly be nice to have a finally keyword. It would save you from having to create a RAII class for every little thing that you want to happen if an exception is thrown (like closing files or DB connections or just writing to a log file...).
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    >> like closing files or DB connections or just writing to a log file...
    I don't necessarily disagree with your sentiment, but those are poor examples, IMO. They are exactly the types of things RAII is best at.

  12. #12
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,411
    I believe cpjust is sick of creating a new class for all kinds of different code.
    So instead of having a finally statement, we'd have to create a new task to execute the code in RAII form instead of the final keyword.

    Well, don't worry, cpjust. C++0x is going to fix that.
    All we need to do is create a RAII class that executes a functor and embed a lambda that is our finally block.
    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.

  13. #13
    Registered User
    Join Date
    Jun 2005
    Posts
    6,163
    Quote Originally Posted by Elysia View Post
    Well, don't worry, cpjust. C++0x is going to fix that.
    All we need to do is create a RAII class that executes a functor and embed a lambda that is our finally block.
    I might be tired today, but fail to see how that addresses cpjust's concern about needing to create a RAII class.

    Personally, I consider that providing a class (eg a sentinel) to encapsulate cleanup code is vastly superior to a finally block. But, then again, it is very rarely I encounter a scenario where cleanup code is only needed in one place - so I consider the reusability of a class an advantage, and prefer to minimise the number of places in code where exceptions actually get caught.
    Right 98% of the time, and don't care about the other 3%.

  14. #14
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,411
    But the issue here is that each function has unique code. Thus it may have to execute some unique code at places. This is what would would wrap in a RAII class. But then you would have to create a new class or function for this unique code for every function. That's a lot of classes and functions you must create to make this RAII work.
    With the finally block, you don't have to create a new class or function to contain that code. Instead you put it inside the finally block, so the code is actually inside the function that needs it. But with lambdas, we can create this unique code inside the function that needs it and wrap it in a RAII class that calls a functor on destruction.
    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.

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,310
    What about the use of Boost.ScopeExit?
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. STL leaking?
    By g4j31a5 in forum C++ Programming
    Replies: 3
    Last Post: 04-03-2009, 01:47 AM
  2. Leaking Memory in a sendmail milter I wrote?
    By stevfletchcom in forum C Programming
    Replies: 8
    Last Post: 10-10-2008, 11:30 AM
  3. leaking mutexes, with no mutex in code
    By bling in forum Windows Programming
    Replies: 5
    Last Post: 10-08-2008, 11:33 AM
  4. Leaking
    By shiver in forum Tech Board
    Replies: 4
    Last Post: 07-05-2006, 07:22 AM
  5. traping leaking memory
    By null in forum C Programming
    Replies: 5
    Last Post: 10-01-2001, 12:02 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21