Jump to content
  • Advertisement
Sign in to follow this  
indigox3

STL vectors and operator delete

This topic is 4709 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Say I have the following:
class B
{

};

class A 
{
public:
std::vector< B > mBs;
};

class C
{
public:
	std::vector< A > mAs;
};

main()
{
	A aa;
	{
		B bb;
		aa.mBs.push_back( bb );
	}

	C* cc = new C;
	cc->mAs.push_back( aa );
	
	delete cc; // STL code is calling delete on elements of the aa's 
}

This pretty much does what you would expect. However, I have some real code similar to this, and delete is getting called (in the bowels of the STL code) on the B elements of A::mBs, when delete is called on cc. This causes a crash (probably because the elements of the vector are stack allocated objects) Why would delete be called on the elements of A::mBs?

Share this post


Link to post
Share on other sites
Advertisement
The elements aren't stack allocated. The vector contains copies of the original values. Furthermore, while the elements' destructors get called when the vector is destroyed, delete isn't "called" on them.

Share this post


Link to post
Share on other sites
I agree that the vector contains copies of the elements I am putting into it. However I'm not sure if the copies created on the stack or heap. (Probably heap thinking about it...)

Along those lines, ~vector() calls _Tidy() calls allocator::deallocate() calls delete with the pointer to the first element of the vector as an argument.

Must be something else going wrong then, I'll keep looking.

Thanks

Share this post


Link to post
Share on other sites
Quote:
Original post by indigox3
I agree that the vector contains copies of the elements I am putting into it. However I'm not sure if the copies created on the stack or heap. (Probably heap thinking about it...)

vector, and all dynamic containers (with the occasional exception of std::string in some implementations), only ever allocate on the heap.

Post your actual code, and we may be able to help.

Share this post


Link to post
Share on other sites
From the sound of it you got a double delete bug comming from not the STL but missing copy and assignment operators in your own classes that probably have some sort of resource (like a pointer to dynamicly allocated memory).

Share this post


Link to post
Share on other sites
Quote:
Original post by indigox3
I agree that the vector contains copies of the elements I am putting into it. However I'm not sure if the copies created on the stack or heap. (Probably heap thinking about it...)

Along those lines, ~vector() calls _Tidy() calls allocator::deallocate() calls delete with the pointer to the first element of the vector as an argument.

Must be something else going wrong then, I'll keep looking.



The allocator's allocate/deallocate methods deals solely with uninitialized memory. The default allocator (std::allocator) uses global operators new/delete via explicit invocation this gives/returns uninitialized memory, allocator's construst/destroy deal soley with de/initialization of uninitialized memory.

Typically (it is imp defined) std::vector is implementated with RAII techniques, std::vector may have a non-polymorphic base that deals with allocation and deallocation in the base destructor, then std::vector just destroys elements in its destructor after which the base deallocates memory.

Quote:
Original post by Sneftel
... only ever allocate on the heap.


Never say never [grin], std::allocator uses heap but give them a custom allocator type that can use what ever you want [wink].

Share this post


Link to post
Share on other sites
I can't post the actual code because of IP issues, but I did comment out pratically everything that could be giving me problems and the code boils down to:

class A : public B
{
public:
std::vector< int > mInts;
A(){};
~A(){};
};

main()
{
A* a = new A();

a->mInts.push_back(12);

...

HomeGrownVector v;
v.push( a );

...

for( int i = 0; i < v.size(); i++)
delete v; // dies here where A::mInts is destroyed.

}

I'm sure "a" isnt being deleted twice, bc I'm breaking on ~A() and its only getting called once.

The homegrown vector might be doing something weird, I'll have to check.

Share this post


Link to post
Share on other sites
You must not delete elements you did not allocate using new. Since you never allocated the elements of v on the heap you must not delete them. just delete a, that will free all memory in your example.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by snk_kid
The allocator's allocate/deallocate methods deals solely with uninitialized memory. The default allocator (std::allocator) uses global operators new/delete via explicit invocation this gives/returns uninitialized memory, allocator's construst/destroy deal soley with de/initialization of uninitialized memory.

Typically (it is imp defined) std::vector is implementated with RAII techniques, std::vector may have a non-polymorphic base that deals with allocation and deallocation in the base destructor, then std::vector just destroys elements in its destructor after which the base deallocates memory.


Wow - what a lot to say very little, still it probably felt intelligent at the time.

More simply, vectors allocate and deallocate memory as required.

If adding objects to a vector like in your example, the vector will allocate memory (on the heap using new) and make copies of your objects. Unless you're using a very old implementation of STL that contains such a bug, it's not a bug in STL. Certainly not one i've encountered anyway.

Share this post


Link to post
Share on other sites
Quote:
Original post by VolkerG
You must not delete elements you did not allocate using new. Since you never allocated the elements of v on the heap you must not delete them. just delete a, that will free all memory in your example.


Oops, I should have been more clear:
the v's are pointers, one of which, is the same as "a".

In other words v is a vector of pointers, not objects

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!