If I have the following:
Do I need to add "delete var" in the catch block? I would fire up valgrind if I had a working linux OS.Code:try { var = new myclass(); } catch (std::exception& e) { std::cout << e.what() << std::endl; return -1; }
If I have the following:
Do I need to add "delete var" in the catch block? I would fire up valgrind if I had a working linux OS.Code:try { var = new myclass(); } catch (std::exception& e) { std::cout << e.what() << std::endl; return -1; }
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)
>> 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.
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"
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
In other languages like C# and Java there is a
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.Code:try { Something } catch(Exception e){ } finally { delete ....; file.close(); }
★ Inferno provides Programming Tutorials in a variety of languages. Join our Programming Forums. ★
But fortunately it has RAII:Unfortunately, C++ doesn't have that.
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.Code:try { file = std::ifstream(somefile); shared_ptr<X> xp(new X); ... } catch (std::exception& ) { ... } //look, no finally!
I might be wrong.
Quoted more than 1000 times (I hope).Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
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.
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
>> 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.
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.
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.
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.
What about the use of Boost.ScopeExit?
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)