I am new to C++ in VS C++. I'm creating win32 dll library. I have a major basic problem with try finally block.
Let's pretend I have something like this:
class object {
private:
int* foo;
public:
object() : foo(new int()) { *foo = 42; }
~object() {
// Now since foo is dynamically allocated, the destructor
// needs to deallocate it
delete foo;
}
};
int main() {
vector<object*> tmp;
tmp.push_back(new object());
// Do some stuff with tmp
for (int i = 0; i < tmp.size(); ++i) {
delete tmp[i]; // Calls ~object (which deallocates tmp[i]->foo)
// and deallocates *tmp[i]
}
tmp.clear();
return 0;
}
I have copied the code snippet from:
Another stackoverflow question
In the above example, how can I use the "free" part so that it could be always freed up as the method finishes its job? I thought try finally should suffice.
But now I can see that there are several: try, __try Don't know what is the difference. With __try I get compiler errors which says something about RAII ...
Could anyone help me with this?
It's Resource Acquisition Is Initialization, RAII for short. The idea there being that if an object owns a resource, its destructor should free it automatically. In all of these cases, with C++11 you'd want to use std::unique_ptr instead of raw pointers. So, for instance:
class object {
std::unique_ptr<int> foo;
public:
object() : foo(std::make_unique<int>(42)) { }
// no destructor necessary here
};
int main() {
std::vector<std::unique_ptr<object>> tmp;
tmp.push_back(std::make_unique<object>());
// when tmp goes out of scope, each object in it will already
// be deleted for you, no code necessary
}
Of the many advantages here is the fact that now you don't have to worry about writing the copy constructor for object (as-is, your foo will get deleted twice if you copy it). See also Rule of Zero
There are various ways.
One is to make the vector<object *> a vector<unique_pointer<object> >. No need to explicitly deallocate the objects at all.
Another is to place the vector<object *> a member of another class that manages the deallocation. So, when an instance of that class is destroyed, its destructor releases all the elements of the vector in your code. You will need to supply other constructors and member functions for that class, to manage adding objects to the vector properly.
Related
If I understand correctly (which I am not claiming I do), you should delete anything created with the new keyword in your Destructor for a particular class. That prevents memory leaks. Example:
#include "Bar.h"
Bar *bar_ = NULL;
Foo::Foo()
{
bar_= new Bar;
}
Foo::~Foo()
{
delete bar_;
bar_ = NULL;
}
But should you delete new things created in main.cpp? Or will they just be automatically deleted by their Destructors when they go out of scope?
#include "Foo.h"
int main()
{
MakeNewFoo();
//Do other stuff and forget foo ever existed
exit(0);
}
void MakeNewFoo(){
Foo *foo = new Foo;
}
Short answer: Yes, clean up your memory.
Longer answer:
I don't know of an OS that won't clean up memory leaks created by you, but you should do it anyway. It becomes especially helpful when you are running a memory leak detection tool, and aren't deluged by a bunch of "false" positives from main.cpp.
Besides, what about something like this?
int main()
{
BigStructure foo* = new BigStructure(/*...*/);
// some computations to get variables
// at this point foo is no longer needed
RestOfProgramFunction1(); // long running, resource heavy
RestOfProgramFunction2(); // long running, resource heavy
}
Now you've held onto a bunch of memory you don't need anymore, which leaves less memory available for the other functions you'll need.
You are responsible for freeing up any memory you allocate. If you don't want to care about when to do it, use a smart pointer like std::unique_ptr or std::shared_ptr, which will free up the memory for you when they go out of scope.
" Or will they just be automatically deleted by their Destructors when they go out of scope?"
No, they wouldn't be deleted, you'll get memory leaks.
In general you don't use new/delete directly in C++. You rather use a smart pointer from the standard Dynamic memory management classes:
class Foo {
unique_ptr<Bar> bar_;
public:
Foo() : bar_(new Bar) {}
~Foo() {} // delete is automatically managed by unique_ptr<Bar>
};
Same for your free function sample:
void MakeNewFoo(){
std::unique_ptr<Foo> foo(new Foo());
// Do stuff with foo
} // Will be deleted as soon foo goes out of scope
But if you use new/new[] you always have to cleanup using delete/delete[], yes.
Everything you create with new will exist during the whole execution of your program in memory, or when it is removed using delete. So yes, you should delete Foo before exiting MakeNewFoo.
First, the code you showed will not compile, because new returns a pointer, but your foo and bar_ variables are not declared as pointers, so you need to fix that:
#include "Bar.h"
Bar *bar_ = NULL;
Foo::Foo()
{
bar_= new Bar;
}
Foo::~Foo()
{
delete bar_;
bar_ = NULL;
}
#include "Foo.h"
int main()
{
MakeNewFoo();
//Do other stuff and forget foo ever existed
exit(0);
}
void MakeNewFoo(){
Foo *foo = new Foo;
}
Now, with that said, you can see that MakeNewFoo() has a memory leak, since the Foo object being allocated with new is never freed using delete. Yes, technically the OS will reclaim the memory when the process terminates. But what if MakeNewFoo() were called in other places of your code besides main()? So it is good practice to always delete whatever you new (or let C++ do it for you, via the std::auto_ptr, std::unique_ptr, and std::shared_ptr smart wrapper classes).
I know that I can't get a reference of a local var. such as:
int& func1()
{
int i;
i = 1;
return i;
}
And I know that this is correct, but I have to delete it after calling func2()
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int *p = func2();
cout << *p << endl;
delete p;
return 0;
}
If the function is like this:
MyClass MyFunction()
{
return new MyClass;
}
MyClass's whole definition is:
class MyClass
{
public:
MyClass() : num(1){}
MyClass(MyClass*) : num(10){}
int num;
};
Will this cause memory leak?
How should I avoid it?
the function returns an object not a pointer, so how can I delete it?
PS: the code comes from the book "Ruminations on C++" Chapter 10.
the original code is:
Picture frame(const Pictrue& pic)
{
// Picture has a constructor Picture(*P_Node)
// Frame_Pic derives from P_Node
// So the constructor Picture(*P_Node) will implicitly convert Frame_Pic to Picture.
return new Frame_Pic(pic);
}
MyClass MyFunction()
{
return new MyClass;
}
This is actually wrong.you are returning a pointer .
so it should be
MyClass* MyFunction()
if your function is as i mentioned above and if you are not deleting it after using it.it will leak memory.
How should I avoid it? the function returns an object not a pointer, so how can I delete it?
that is a compilation error.so the point of deleting it will not rise
If you delete the pointer returned from the funciton there is no memory leak. However this is error prone since it means that every client of the function must know that it should delete the return value. It's much better style to use a smart pointer (either shared_ptr or unique_ptr according to semantics).
The same goes to the Picture example. If this object correctly manages its resources (i.e. deletes in the destructor and has a good copy constructor and operator= (in accordance with the Rule of Three), then there is no memory leak.
With your updated MyClass that has the pointer constructor, I suppose you should write:
MyClass MyFunction() {
MyClass *ptr = new MyClass;
MyClass retval(ptr);
delete ptr; // the dynamically-allocated object isn't needed any more
return retval;
}
That happens to be exception-safe, since the constructor of MyClass can't throw, but as a general rule you really shouldn't ever call new without putting the result straight into a smart pointer:
MyClass MyFunction() {
std::unique_ptr<MyClass>(new MyClass);
return MyClass(ptr);
}
It's a fairly absurd situation anyway - if you're going to return by value, there's no reason to call new at all:
MyClass MyFunction() {
MyClass tmpvalue;
return &tmpvalue; // doesn't actually return the pointer, just an object
// constructed from it
}
And since the value of the pointer isn't even used by the pointer constructor, you could just as well write:
MyClass MyFunction() {
return 0; // returns an object constructed from a null pointer
}
In the original code your quote from the book, I guess that the class Picture has a data member of type P_Node*, in which it stores the pointer value, and calls delete on that pointer in its destructor. Hopefully the author also does something about the copy constructor and copy assignment operator of Picture, to prevent a double-free after the copy. I don't have the book, so I can't check my guess, but the code for Picture should show how it's done.
[Edit: oh, that's one of the books by Koenig and Moo. They are (more than) competent, so pretty certainly their Picture class handles the resource correctly. If it doesn't, it's because it's a deliberate example of Doing It Wrong.]
It's the same as your "func2" example. who ever call "frame" need to free the returning Picture in the end.
MyClass MyFunction()
{
return new MyClass;
}
is incorrect, because operator new returns a pointer to MyClass, but your function returns MyClass, not MyClass*
A simple check would be this:
If you're using N number of new in your program, then you've to use N number of compatible1 delete in your program to avoid memory leak2.
So are you doing that? Yes, in the first case (in which you're doing new int) you're doint that. There is no memory leak.
And rest of the post isn't clear enough to me!
1. By compatible delete, I mean if you're using new in the form of ptr = new T[M], then the compatible delete should be of the form of delete []ptr. Similarly, delete ptr is compatible with ptr = new T.
2. Of course, if you're using some smart pointers, then you don't have to use delete explictly.
I am not experienced in handling of the memory in a C++ program, so I would like a piece of advice in that case:
I want to create a new Object in a function in a class which is essential till the end of the program. As far as I am concerned, if I use the operator new, I should sometimes delete it. Taking into account that it must be initialized inside a class, when and how must I finally delete it?
I suggest the smart pointer idiom
#include <memory>
struct X
{
void foo() { }
};
std::share_ptr<X> makeX() // could also be a class member of course
{
return std::make_shared<X>();
}
int main()
{
std::share_ptr<X> stayaround = makeX();
// can just be used like an ordinary pointer:
stayaround->foo();
// auto-deletes <sup>1</sup>
}
If the pointer is truly a static variable, you can substitute a unique_ptr (which works similarly, but passes ownership on assignment; this means that the pointer doesn't have to keep a reference count)
Note To learn more about C++ smart pointers in general, see smart pointers (boost) explained
Note If you don't have the TR1/C++0x support for this, you can just use Boost Smartpointer
1 unless you are leaking copies of the shared_ptr itself; that would be some strange use of smart pointers previously unseen :)
Edit: Using some sort of smart pointer is often a good idea, but I believe it is still essential to have a solid understanding of manual memory management in C++.
If you want an object in a class to persist until the end of the program, you can simply make it a member variable. From what you've said, there's nothing to suggest you need to use new or delete here, just make it an automatic variable. If you did want to use new and delete for practice, you should read up on constructors and destructors for a class (you can and will use new and delete outside of classes, but I'm trying to keep this relevant to your question). Here's one I prepared earlier:
class Foo
{
public:
Foo(); // Default constructor.
~Foo(); // Destructor.
private:
int *member;
}
Foo::Foo() // Default constructor definition.
{
member = new int; // Creating a new int on the heap.
}
Foo::~Foo() // Destructor.
{
delete member; // Free up the memory that was allocated in the constructor.
}
This is a simple example, but it will hopefully help you out. Note that the variable will only persist as long as the object is alive. If the object is destroyed or goes out of scope, the destructor will be called and the memory will be freed.
You can use the smart pointer as suggested by Sehe or you can create a static object in the function and return a reference to it. You need not explictly delete the object, when the process terminates the object will be deleted. Like:
struct X {};
X& makeX() // could also be a class member of course
{
static X x;
return x;
}
int main()
{
X& stayaround = makeX();
}
On most operating systems (in particular Linux), if you allocate an object pointer with new Object, and don't bother delete-ing because you'll need it till the program ends, no harm is really done. There is some memory leak inside your program (you can use valgrind to hunt such leaks) but the kernel will release all the memory used by a process when it has ended.
A better alternative is to have a singleton class for the application data, like e.g. QApplication in Qt, ahd construct a single instance in that class early in your main, and have that class contain a smart or dumb pointer to your Object. The destructor should delete that object.
Say for example i have the following code (pure example):
class a {
int * p;
public:
a() {
p = new int;
}
~a() {
delete p;
}
};
a * returnnew() {
a retval;
return(&retval);
}
int main() {
a * foo = returnnew();
return 0;
}
In returnnew(), would retval be destructed after the return of the function (when retval goes out of scope)? Or would it disable automatic destruction after i returned the address and i would be able to say delete foo; at the end of main()? Or, in a similar vein (pseudocode):
void foo(void* arg) {
bar = (a*)arg;
//do stuff
exit_thread();
}
int main() {
while(true) {
a asdf;
create_thread(foo, (void*)&asdf);
}
return 0;
}
where would the destructor go? where would i have to say delete? or is this undefined behavior? Would the only possible solution be to use the STL referenced-counted pointers? how would this be implemented?
Thank you- i've used C++ for a while but never quite been in this type of situation, and don't want to create memory leaks.
For a stack created object, the destructor is automatically called when the object goes out of scope.
For an object created on the heap, the memory will be freed only when you explicitly call delete.
Whether you return the address of a stack created object from a function or not does not matter. The destructor will still be called when the item goes out of scope.
So for your code example:
a * returnnew()
{
a retval;
return(&retval);
}
a's destructor is called before the code jumps back to the code that calls returnnew(). You return the address of that object, but that address is pointing to a place in memory that no longer belongs to you.
Where would i have to say delete?
You only use delete when you used new
You only use delete[] if you used new[]
or is this undefined behavior?
What you do with the address of memory that doesn't belong to you will be undefined behavior. It is not correct code though.
Would the only possible solution be to use the STL referenced-counted pointers?
You could return the object by value, or you could create a new object on the heap. You can also pass in the object to the function via a parameter and ask the function to change it.
how would this be implemented?
//Shows how to fill an object's value by reference
void fillA(a& mya)
{
mya.var = 3;
}
//Shows how to return a value on the heap
a* returnNewA()
{
//Caller is responsible for deleting the returned pointer.
return new a();
}
//Shows how to return by value, memory should not be freed, copy will be returned
a returnA()
{
return a();
}
a * returnnew() {
a retval;
return(&retval);
}
Here, retval has automatic storage duration, which means that the language will automatically destruct it when it goes out of scope. The address you've returned refers to an object that no longer exists, and trying to use the return value will be an error.
When you want an object's lifetime to be controlled by you, you have to use the new operator to create it.
a* returnnew()
{
a* retval = new a();
return retval;
}
Here, you now have complete control over the lifetime of this a. It will live until you explicitly delete it, or your program ends.
You could also come up with meaningful copy semantics for your a class, and return it by value, in which case your caller would get his own copy, distinct from the original. Then, your caller doesn't care when the original goes away.
class a
{
int * p;
public:
a(a const& rhs)
{
p = new int(rhs.p)
}
a()
{
p = new int;
}
~a()
{
delete p;
}
};
Now, you can construct a fresh a as a copy of an existing a. So your function could then return an a by value, like so:
a returnnew()
{
a retval;
return retval;
}
Here retval's lifetime will end when the function returns, and it will be destructed automatically by the language, and no resources will be leaked. And your caller will have his own copy, with its own lifetime.
In my experience, most classes should have sensible copy semantics, and you should not be afraid to pass and return them by value. It's just simpler that way, and you'll avoid dangling pointer problems.
One of C++'s biggest strengths is the way that destructors are automatically called by the language when automatic storage duration objects go out of scope. If you ensure that every resource in your program is owned by such an object, you'll have a much harder time leaking resources.
As a general rule the easiest way to avoid memory leaks in C++ is to avoid using new and delete as much as possible.
If you must have a pointer to something use a smart pointer (such as a boost scoped_ptr or shared_ptr). This way you can still have your object on the heap, but it's deconstructor will be called when the smart pointer goes out of scope. Otherwise trying to be sure that you call delete in every case can be a headache and cause a lot of extra code.
+1 to Brian's answer, just want to add a comment about the threading aspect.
Your code to create a thread is going to destroy the asdf object that you passed to the thread function regardless of the child, because asdf is on the parent stack. Either create asdf on the heap, or pass by value. Otherwise, the parent will destroy asdf, and leave your child thread pointing to a bad address on the parent's stack. Not good in any case, destructors or no destructors. The only way you'd safely pass asdf to a function in a thread would be if you created the thread first, and asdf was a stack object in ITS stack, not the parent stack.
void foo(void* arg) {
bar = (a*)arg; // child has reference to a parent stack address!
//do stuff
exit_thread();
}
int main() {
while(true) {
a asdf; // parent stack
create_thread(foo, (void*)&asdf); // parent and child diverge here, asdf auto-destroyed
}
return 0;
}
In the case of the following code:
void foo(void* arg) {
bar = (a*)arg;
//do stuff
exit_thread();
}
int main() {
while(true) {
a asdf;
create_thread(foo, (void*)&asdf);
}
return 0;
}
The destructor is called at the closing brace of the while loop. This means it will be called every iteration of the loop (and the will be constructed again for the next iteration).
As a useful tool in exploring the nuances of constructors and destructors and scopes, consider using the following class to help you answer these questions by yourself in the future:
class trace {
private:
std::string msg_;
public:
explicit trace(const std::string &msg) : msg_(msg) {
std::cerr << "Constructing: " << msg_ << std::endl;
}
~trace() {
std::cerr << "Destructing: " << msg_ << std::endl;
}
};
Use it thusly:
trace glb("global");
main() {
trace t1("top of main");
for(int i = 0; i < 10; ++i)
{
trace t2("inside for");
}
return 0;
}
The results may surprise you.
returnnew() will destroy the variable upon return because you're returning a pointer to a local variable. If you want to return retval from there, allocate it dinamically, eg:
a * returnnew() {
a * retval = new a;
return retval;
}
Or just:
a * returnnew() {
return new a;
}
Dynamic allocated memory has no scope, and thus won't be deallocated until you say so, by means of a delete/delete[]/free, or until the program exits (and few other cases not related to the question). Before anyone comments here, my "until you say so" also includes shared/smart/etc pointer behaviour.
As for your second code & questions, if you are allocating the variable outside the thread, but ONLY using it from inside, you can just make the thread deallocate (delete) it when it's no longer needed. However, if you plan to access the variable from multiple points, and you can't guess when you're safe to destroy it, surely, use a smart or shared pointer.
I am using borland 2006 c++, and have following code. I am using vectors, and have trouble understanding why the destructor is not being called.
basically i have a class A
class A
{
private:
TObjectList* list;
int myid;
public:
__fastcall A(int);
__fastcall ~A();
};
__fastcall A::A(int num)
{
myid = num;
list = new TObjectList();
}
__fastcall A::~A()
{
delete list;
}
int main(int argc, char* argv[])
{
myfunc();
return 0;
}
void myfunc()
{
vector<A*> vec;
vec.push_back(new A(1));
vec.push_back(new A(2));
}
according to what i read, when variable vec goes out of scope in myfunc(), it should destruct its contained elements, so the destructor for A should be called. I have a breakpoint at ~A(), but never gets called, i have tried resize(), erase methods also
TIA
vec does destruct its elements when it goes out of scope. The problem here is that vec's elements are the pointers to A objects, not A objects themselves. If you instead did
vector<A> vec;
vec.push_back(A(1));
vec.push_back(A(2));
...then things would work as you expect.
ETA: note, though, that if you do this you have to define a copy constructor for A. That should involve doing a deep copy of the TObjectList member. Otherwise, when you copy an A object you'll wind up with two objects both pointing to the same TObjectList, and your program will crash when the second object is destroyed.
The destructor for A isn't called because you don't have a vector of A. You have a vector of pointers to A, and the destructors for the pointers are called. Pointers don't have a destructor, so nothing happens.
One way to delete everything would be to manually do something like
while (!vec.empty())
{
delete vec.back();
vec.pop_back();
}
Lots of good answers already, but I'll add one more:
Use boost::ptr_vector from the Boost Pointer Container Library, instead of std::vector. It will delete the objects when the vector goes out of scope, thus calling the destructors.
Grab the Boost libraries, and wherever you have a raw pointer in the above you use boost::shared_ptr<> instead. (Well, not in the signature of main().)