c++ garbage values in vector of pointer

前端 未结 6 1932
青春惊慌失措
青春惊慌失措 2020-12-22 00:12

When I do:

for(i=0; i

s

相关标签:
6条回答
  • 2020-12-22 00:17

    When you do vectorA.push_back you may cause that vector to reallocate itself to increase capacity, which means all its contents are moved, which means any pointers to its contents that you have saved are made invalid.

    Maybe you want to rethink the whole idea of storing pointers to elements of a vector.

    If you can't drop the whole idea of storing pointers, but you know the required size in advance, you could use reserve before the loop:

    vectorA.reserve(size);
    for(i=0; i<size; i++){
        //create objectA here
        vectorA.push_back(objectA);
        pvectorA.push_back(&vectorA[i]);
    }
    

    In this version, the pointers are valid until you either grow vectorA further or destroy it.

    0 讨论(0)
  • 2020-12-22 00:24

    Read the documentation of std::vector::push_back

    First the description:

    Adds a new element at the end of the vector, after its current last element. The content of val is copied (or moved) to the new element.

    This effectively increases the container size by one, which causes an automatic reallocation of the allocated storage space if -and only if- the new vector size surpasses the current vector capacity.

    Then about validity of iterators:

    If a reallocation happens, all iterators, pointers and references related to the container are invalidated.

    So, when you add an object to the vector, all the pointers pointing to objects in that vector may become invalid - unless you've guaranteed that the vector has enough capacity with std::vector::reserve.

    Invalid means that the pointer no longer points to a valid object and dereferencing it will have undefined behaviour.

    In the latter code, you never add objects to the pointed-to vector after you've stored the pointers, so the pointers are valid.

    0 讨论(0)
  • 2020-12-22 00:30

    When you push elements into vectorA it will occasionally get full, and have to relocate its objects to a larger memory block. That will change the address of each element.

    If pvectorA has stored pointers to the elements' original position, those pointers will still point to the old positions even after the vectorA elements have been moved to a new location.

    0 讨论(0)
  • 2020-12-22 00:31

    This is because the vector reallocated its internal storage when it grows beyond its current capacity; after the reallocation, the address of elements may have changed.

    You can avoid reallocation by reserving a big enough storage beforehand:

    vectorA.reserve(size);
    //vectorB.reserve(size); // this would not hurt either
    for(i=0; i<size; i++){
      //create objectA here
      vectorA.push_back(objectA);
      pvectorA.push_back(&vectorA[i]);
    }
    

    One final note: if you can use C++11, emplace_back constructs your object in place, hence, without copying.

    0 讨论(0)
  • 2020-12-22 00:32

    If you want a sequence container with constant-time insertion and no invalidation of iterators pointing to other elements, use a std::list. Note however that std::vector is often the fastest data structure to use (in some cases, you need a pre-sorted std::vector). One prominent reason for this is that arrays are more cache friendly than e.g. trees or linked lists.

    0 讨论(0)
  • 2020-12-22 00:34

    When you use push_back to add an element to a vector, it is copied into the vector. The means that, in the first example, vectorA contains a copy of objectA, and objectA goes out of scope and gets deleted right after the closing brace. This means that the pointer in pvectorA is pointing at at an address that doesn't necessarily contain objectA any more.

    Your second example shouldn't work, because objectA has gone out of scope after the first loop, so I can't help you there.

    0 讨论(0)
提交回复
热议问题