Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Kranar

STL vector frustrations

This topic is 5181 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

Is there any reason why pushing back an element into a vector causes the destructor of all elements to be called? I understand that when you pushback to a vector, the vector has to allocate more space, and move all the elements to the newly allocated space, but to call the destructor of every element in doing so seems absurd. Is there a way to stop this from happening?

Share this post


Link to post
Share on other sites
Advertisement
I don''t think thats correct if your using push_back but if it is the case you can use the "reserve" method to avoid reallocations

Share this post


Link to post
Share on other sites
Well, if the elements are moved to another location in memory, the previous location has to be freed, including any dynamic memory that any of the vector elements may have had. I look at it this way, if there is anything for a destructor to do it will do it, if an element/object within the vector has no need to do any cleanup, then then there is nothing to destroy and things go fine. Destructors are there because its necessary. I can''t really see any other way to put it.

Share this post


Link to post
Share on other sites
quote:
Original post by snk_kid
I don''t think thats correct if your using push_back but if it is the case you can use the "reserve" method to avoid reallocations


I did a very simple experiment to make sure that I''m not just crazy.


#include <iostream>
#include <vector>
#include <conio.h>

using namespace std;

class A {
public:
A() {}
~A() {
cout << "Why are you doing this to me?" << endl;
}
};

int main() {
vector<A> test;
A a;
const int repeats = 2;
for(int i = 0; i < repeats; i++) {
test.push_back(a);
}
getch();
return 0;
}


Before the getch(), I get my message printed out 3 times. When repeats = 5, I get my message printed out 15 times. Everytime I push back, with the exception of the initial push back, the message in A''s destructor is printed out.

This is frustrating me because the destructor in my class needs to free the memory it allocated when the class terminates.

Share this post


Link to post
Share on other sites
In other words... the following will crash


#include <iostream>
#include <vector>
#include <conio.h>

using namespace std;

class A {
public:
A() {
x = new int(0);
}
~A() {
delete x;
}
private:
int* x;
};

int main() {
vector<A> test;
A a;
const int repeats = 2;
for(int i = 0; i < repeats; i++) {
test.push_back(a);
}
getch();
return 0;
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
You need a copy constructor and an assignment operator.

Share this post


Link to post
Share on other sites
quite quite simple really, the STL containers work on a copy prinicple, so when memory has to be reallocated and objects move they are infact copied via the copy constuctor.

In your example what you need to do is create a copy constuctor which does teh ''new'' and then copies the data from the old location so it can be free''d when the old copy is deallocated.

The other way around this is to store pointers or smart pointers to objects in your list, then the pointers will be copied around and objects wont be deleted/deallocated on resize.

Share this post


Link to post
Share on other sites
Take Anonymous Poster advice, make an apprioate copy and assignment operator. At the moment you have default copy constructor automaically created that just copies address.

The reason why its going to crash is because when you create a container of objects with your class setup like that.
In your previous example this is whats happening.

You create one instance, new is called once inside its constructor, then each time you push is back it makes a copy of the object thus copying the address. When the program exits, all the elements plus the first variable are destroyed calling delete 3 times on the same location and crashes.


[edited by - snk_kid on June 9, 2004 4:50:39 PM]

Share this post


Link to post
Share on other sites
Call test.reserve(repeats); to reserve memory and avoid reallocations. After a call to reserve(n), you can push_back() up to n total elements, and nothing will ever be reallocated, and destructors will never be called.

Share this post


Link to post
Share on other sites
another thing you can do to avoid the destructors being called is to store a vector of pointers to dynamically allocated objects. This requires less vector space and quicker resizes and copies, but you do have to remember to delete the objects before you clear the vector.

"That''s not a bug, it''s a feature!"
--me

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!