vector pointer locations guaranteed?

前端 未结 7 1660
无人及你
无人及你 2021-01-05 01:05

Suppose I have a vector of ints,

std::vector numbers;

that is populated with a bunch of values, then I say do this (where an ent

相关标签:
7条回答
  • 2021-01-05 01:20

    Pointers, references, and iterators to std::vector elements are guaranteed to stay put as long as you only append to the std::vector and the size of the std::vector doesn't grow beyond its capacity() at the time the pointer, reference, or iterator was obtained. Once it gets resized beyond the capacity() all pointers, references, and iterators to this std::vector become invalidated. Note that things are invalidated as well when inserting somewhere else than the end of the std::vector.

    If you want to have your objects stay put and you only insert new elements at the end or the beginning, you can use std::deque. Pointers and references to elements in the std::deque get only invalidated when you insert into the middle of the std::deque or when removing from the middle or when removing the referenced object. Note that iterators to elements in the std::deque get invalidated every time you insert an element into the std::deque or remove any element from it.

    0 讨论(0)
  • 2021-01-05 01:22

    As all the others have said, when you call .resize() on a vector your pointers become invalidated because the (old array) may be completely deallocated, and an entirely new one may be re-allocated and your data copied into it.

    One workaround for this is don't store pointers into an STL vector. Instead, store integer indices.

    So in your example,

    std::vector<int> numbers;
    int *oneNumber = &numbers[43]; // no. pointers invalidated after .resize or possibly .push_back.
    int oneNumberIndex = 43 ;      // yes. indices remain valid through .resize/.push_back
    
    0 讨论(0)
  • 2021-01-05 01:27

    When you use a vector's resize() or reserve() function to increase the capacity of the vector, it may need to reallocate memory for the array-backing. If it does reallocate, the new memory will not be located at the same address, so the address stored in oneNumber will no longer point to the right place.

    Again, this depends on how many elements the vector is currently being used to store and the requested size. Depending on the specifics, the vector may be able to resize without reallocating, but you should definitely not assume that this will be the case.

    0 讨论(0)
  • 2021-01-05 01:33

    Is oneNumber guaranteed to always be pointing at the int at index 43

    Yes, this is guaranteed by the standard.

    even if say I resize numbers to something like numbers.resize(46)?

    No. Once you resize, add, or remove anything to the vector, all addresses and iterators to it are invalidated. This is because the vector may need to be reallocated with new memory locations.

    0 讨论(0)
  • 2021-01-05 01:33

    Once you changed the capacity of the vector, the data was copied to another memory block, and the origin data is deleted.

    0 讨论(0)
  • 2021-01-05 01:38

    No - the vector can be reallocated when it grows. Usually once the vector doubles in size.

    From the C++11 standard

    1 Remarks: Causes reallocation if the new size is greater than the old capacity. If no
    reallocation happens, all the iterators and references before the insertion point
    remain valid. If an exception is thrown other than by the copy constructor, move 
    constructor, assignment operator, or move assignment operator of T or by any 
    InputIterator operation there are no effects. If an exception is thrown by the move 
    constructor of a non-CopyInsertable T, the effects are unspecified.
    
    0 讨论(0)
提交回复
热议问题