Felix
Felix

Reputation: 31

drawback to vector.reserve(10000000) because i want to keep original memory locations?

I'm creating objects at runtime with vector.push_back() and i want to store the player object so i can use it whenever i want. So i store the pointer of the just created player to a global pointer variable, but when i push back the next object, the memory adress of the player changes, i think because the vector has to resize and therefore changes all of its elements locations.

for (int y = 0; y < 5; y++)
{
    for (int x = 0; x < 10; x++)
    {
        switch (map[x + 10 * y])
        {
        case '1':
            gameObjects.push_back(player);
            playerPointer = &gameObjects.back();
            break;
        case '2':
            gameObjects.push_back(block);
            gameObjects.back().transform.pos = vec((float)x * 100, (float)y * 150, 0);
            break;
        }
    }
}

but when i use

gameObjects.reserve(10000);

the location doesnt change, because its reserved and doesnt need to resize until the size becomes 10000 in this case.

So whats the catch? can you just reserve(1000000000) with no consequences? my RAM usage doesnt skyrocket.

Thanks in advance

Upvotes: 0

Views: 74

Answers (2)

Felix
Felix

Reputation: 31

quickly after i posted this i realized that using pointers as an ID is stupid (especially with vectors) so i just gave the gameobject a const char* name and made a function which loops trough my gameobjects till it finds one with the name you seek and returns it. The i set a GameObject* to the gameobject* the function returns and from there i can use player->doStuff

Upvotes: 0

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123460

The drawback of reserve( a lot ) is that you can either reserve far too much, which is a waste of memory, or too little, then reallocations will still happen.

Pointers to elements get invalidated when iterators get invalidated. For when iterators get invalidated I refer you to this question: Iterator invalidation rules.

Face it: std::vectors iterators are rather unstable (and thus also pointers to elements). You have several options:

  • Reserving enough space upfront can be a solution, though it isn't safe. Once you push more than you reserved, iterators are off.
  • When you are fine with reserving enough space for the maximum number of elements you can as well use a std::array.
  • Use indices. Assuming you do not reorder the vector and you never remove elements, indices are stable.
  • Use a std::list. Iterators of lists are much more stable than iterators into vectors. In particular, inserting to a list does not invalidate iterators. Though, consider the drawbacks of std::list compared to std::vector.
  • Store the elements elsewhere. Instead of storing the player in the vector you can store a (smart-) pointer to it in the vector. Reordering or reallocating the vector will then not affect pointers to the actual objects.

Upvotes: 4

Related Questions