Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Avoiding memory leaks when deleting objects from a vector? 1

Status
Not open for further replies.

VBDotNetProgrammer

Programmer
Jul 9, 2003
50
0
0
GB
Hi,

Im concerened with memory leaks when deleting objects from vectors i.e.

I am adding objects to the vector like such

<code>

for(i = 0; i < vRules.size(); i++)
{
_vRules.push_back(CRule(vRules));
}

</code>

What would be the correct way to delete the object in that vector? Im afraid I am simply deleting its reference and that the object is being lost as a memory leak?

Thanks
 
vector<Class> contains its own copies of push_backed objects.
For example, try the snippet to understand vector<> container logics:
Code:
class V
{
  static int cnt; // objects counter.
  int num; // this object number
public:
  V()  { num = ++cnt; cout << "ctor " << num << endl; }
  V(const V& v) // copy ctor
  { 
    num = ++cnt; 
    cout << "copy " << num << " = " << v << endl; 
  }
  ~V() { cout << "dtor " << num << endl; }
//	static int getCnt() { return cnt; }
  operator int() const { return num; }
};

int V::cnt = 0;

void Vect()
{
	cout << "enter..." << endl;
	vector<V> v;
	V	v1, v2;
	cout << "push(v1): ";
	v.push_back(v1); // see working objects
	cout << "push(v2): ";
	v.push_back(v2); // see new objects in the vector
	cout << "pop: ";
	v.pop_back();
	cout << "exit..." << endl; // see 1, 2 dtors
}
 
Indeed, the STL class vector takes care of it's own allaction and deallocation...

If your writting your own version of a dynamic array (read: vector type class) then you'll want to handle it in your resize, remove/erase and destructor.

If your keeping a vector of object pointers that hold on to dynamically allocated memory (useful for polymorphism) then you need to deallocate the thing the pointer you pushed is pointing to, and the pointer it's self will be destroyed by the vector class's pop or erase.
 
Of course, if you're pushing pointers to objects onto the vector, you should probably be pushing smart pointers in the first place. That way, when the vector deletes the pointer, the pointed-to object gets deallocated, too.


Also, note that, when you put an object into a vector, you're really putting a copy of the object into the vector. That copy lives in the vector-managed memory, and the vector is responsible for deleting it. The original is still wherever you left it, so you might need to delete the original on your own.

In your example, unless [tt]CRule(vRules)[/tt] returns a bare pointer to something that needs to get deleted, you are no longer responsible for the copy once you "give" it to the vector.
 
Thanks guys, most informative as ever!

CRule(vRules) is the constructor of the object i am creating and as you can see it is only being called in the vector and as a result I should hopefully not have to do anything about it.

Smart pointers? Does anyone have any good links?

Thanks
 

Also, check out any C++ reference for [tt]auto_ptr[/tt], which is in the same family, but somehow got lucky enough to make it into the Standard.

I also recall an article at about a non-owning smart pointer that didn't delete anything, and whose only purpose was to document that it wouldn't be deleting anything when it died. Along with the Boost pointers and [tt]auto_ptr[/tt], that would keep you from ever using a "real" pointer ever again.


Finally, check out a different take on smart pointers in the Loki library. You can get it at and you can read about them in the book Modern C++ Design by Andrei Alexandrescu.


As for your example, here's what happens. Your constructor constructs a temporary object. That object gets passed to the [tt]push_back[/tt] function, which makes a copy of it in some vector-managed dynamic memory. As soon as the statement that calls [tt]push_back[/tt] ends, the destructor for your original object gets called, as it has gone out of scope. The copy, of course, lives on. As soon as the vector goes out of scope (or it gets deleted, or you explicitly call its destructor), it cleans up all its memory, including that memory containing the copy of the original object.
 
An extra note about smart pointers and containers like vector:

You should not use auto_ptr and other smart pointers with similar copy semantics in STL containers. This is because the auto_ptr transfers ownership when it is copied (thereby modifying the source of the copy). In the implementation of STL containers, copies are used all over the place, and so you could easily end up with a temporary copy getting ownership of the pointer, then deleting it prematurely when it is destroyed.
 
Good point, uolj. Of the Boost smart pointers, [tt]shared_ptr[/tt] and its friend [tt]weak_ptr[/tt] are safe to use in STL containers. Boost recommends that you replace most normal uses of pointers with [tt]shared_ptr[/tt], which is normally The Right Choice, and downgrade it to something stricter like [tt]aoto_[/tt] or [tt]scoped_[/tt] when you know it fits.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top