Jump to content
  • Advertisement
Sign in to follow this  
VQuery

[Easy] C++ Vector store Vs Array store [Issue]

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

Essentially I have DoorObject which extends WorldObject. DoorObject is placed into a separate store to avoid slicing; instead I have a vector of the base pointer which  gathers all "world objects".

Now below in this first method I'm using a vector of "DoorObject"s which is having random memory issues which are hard to point. Whenever I add a second item to the vector, either random fields become uninitialized or the pointers aren't pointing correctly (probably this). 

Declarations 1:
std::map<int, std::vector<WorldObject*>> WorldObjectManager::Objects;
std::vector<DoorObject> DoorObjects = std::vector<DoorObject>();


Functions 1:
DoorObjects.push_back(DoorObject(WorldObject(xyz), xyz));
Objects.at(int).push_back(&(*std::prev(DoorObjects.end())));

//This also doesn't help:
//Objects.at(region).push_back(&DoorObjects.at(DoorObjects.size()-1));
 
However when I use an array like below, everything is just dandy. 
 
Declarations 2:
std::map<int, std::vector<WorldObject*>> WorldObjectManager::Objects;
DoorObject* Doors = new DoorObject[256];
int count;


Functions 2:
Doors[count] = DoorObject(WorldObject(xyz), xyz);
Objects.at(int).push_back(&(Doors[count]));
count++;

Any insight possibly into what's going on?

Edited by VQuery

Share this post


Link to post
Share on other sites
Advertisement
Vectors can resize. When that happens, the items inside them can move to new locations. Any pointers to those items, including iterators, are invalid after something is added.

Fixed-length arrays like you describe don't move, they are a stationary block of memory. The pointers will remain valid as long as the items remain in the array at that location.

Share this post


Link to post
Share on other sites

Vectors can resize. When that happens, the items inside them can move to new locations. Any pointers to those items, including iterators, are invalid after something is added.

Fixed-length arrays like you describe don't move, they are a stationary block of memory. The pointers will remain valid as long as the items remain in the array at that location.

 

Thanks! Kind of figured as much but I really didn't expect the vector to be resized after adding a second item. I suppose I could have looked into default length?

This seems to be working for me:

Objects.at(xyz).push_back(new DoorObject(WorldObject(xyz), xyz));

Share this post


Link to post
Share on other sites

This seems to be working for me:
Objects.at(xyz).push_back(new DoorObject(WorldObject(xyz), xyz));

 

That would work for allocation indeed.

Removal is now somewhat tricky, deleting an entry from the array now doesn't delete the object. You may want to use a standard pointer object like std::unique_ptr<> instead of a bare pointer.

Share this post


Link to post
Share on other sites

I really didn't expect the vector to be resized after adding a second item. I suppose I could have looked into default length?
 

 

You can reserve space in a vector with the .reserve() method.  It ensures there is enough space and does the reservation only once.  There are still operations that can cause it to resize, so still no guarantee about it staying put.

 

This seems to be working for me

 

Not really.  The 'new' statement in the middle can trip you up in various unexpected ways. 

 

I don't have time to go into a longer explanation, your code really needs to address object lifetimes.  When exactly is it created? When exactly is it destroyed?  Where exactly will the instances live?  How will you ensure that references/pointers to the object remain valid over the object's lifetime?

Share this post


Link to post
Share on other sites

This seems to be working for me: Objects.at(xyz).push_back(new DoorObject(WorldObject(xyz), xyz));
 

 

But understand that that is doing something different. You're allocating individual DoorObjects on the heap, instead of them existing in a contiguous block memory. Not to mention that your object ownership semantics have completely changed. Before the object was "owned" by the array/vector of DoorObjects. Now the only one with a pointer is the Object maps - you'll need to remember to delete the DoorObject* when you remove it from Objects.

 

If Objects is the owner of the things it contains, they should probably be unique_ptr's to express this, i.e.:

std::map<int, std::vector<std::unique_ptr<WorldObject>>> WorldObjectManager::Objects;

Or you could go back to your original way of doing it, and use fixed arrays, and assume a maximum number of DoorObjects that you would ever have. Or use vector, but call reserve(x) on it, where x is whatever your max number of doors is.

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.

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!