Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does resizing an STL vector erase/invalidate its previous contents?

Tags:

c++

stl

vector

It doesn't appear to (sample program), but can I be sure?

// does resizing an STL vector erase/invalidate it's previous contents?
#include <stdio.h>
#include <vector>
using namespace std ;

void print( vector<int>& t )
{
  for( int i = 0 ; i < t.size() ; i++ )
    printf( "%d ", t[i] ) ;
  puts("");
}

int main()
{
  vector<int> t ;
  t.resize( 12,9999 ) ;
  print(t) ;

  t.resize( 15, 10000 ) ;
  print(t) ;
}
like image 651
bobobobo Avatar asked Mar 06 '12 21:03

bobobobo


People also ask

What happens when a vector is resized?

vector::resize() The function alters the container's content in actual by inserting or deleting the elements from it. It happens so, If the given value of n is less than the size at present then extra elements are demolished.

Does vector resize keep values?

Yes, when you shrink a vector, all the objects that remain retain their prior values. When you expand a vector, you supply a parameter specifying a value that will be used to fill the new slots.

Does vector erase change vector size?

The size is changed then an element of a vector is removed with using member function erase. If you mean capacity then it will not be changed.

Does vector erase shift?

Logically yes, as a vector is a dynamic array of element. You delete one, then everything that follows is moved. In the same manner, the total length of the vector will decrease as you erase elements.


3 Answers

Resizing an STL vector may require reallocating the underlying storage. This may cause any number of elements to be destroyed and recreated, and all iterators are invalidated. Accessing an invalidated iterator is a common source of errors when using the STL.

The contents of each element will be the same, unless the copy constructor doesn't work.

int main(int argc, char *argv[])
{
    int data[] = { 1, 2, 3 };

    std::vector vec(data, data + 3);
    // vector contains 1, 2, 3

    std::vector::iterator i = vec.begin();
    cout << *i << endl; // prints 1
    int &ref = *i;
    cout << ref << endl; // prints 1

    vec.resize(6, 99);
    // vector now contains 1, 2, 3, 99, 99, 99

    // WRONG! may crash, may do the wrong thing, might work...
    // cout << *i << endl;

    // WRONG! invalid reference
    // cout << ref << endl;

    return 0;
}
like image 164
Dietrich Epp Avatar answered Oct 10 '22 10:10

Dietrich Epp


resize will invalidate all iterators, pointers, and references into the std::vector if and only if the new size is larger than the current capacity of the container (i.e., v.capacity()).

The elements in the container are never "invalidated." If you resize the container to be smaller than its current size, any extra elements beyond the new size are destroyed.

If you resize the container such that the new size is larger than the current capacity and a reallocation of the underlying storage is required, all elements are copied or moved into newly-allocated storage. When you enlarge a container, the previous elements are always retained, just moved or copied to new locations in memory.

like image 41
James McNellis Avatar answered Oct 10 '22 09:10

James McNellis


Resizing a vector doesn't destroy the values stored in the vector (except for those beyond the new size when shrinking, of course), however growing a vector beyond its capacity will copy (or, in C++11, move) them to a new place, thus invalidating and iterators, pointers or references to those elements.

In your example program you do not store iterators, pointers or references to vector elements during the resize, therefore you access the copied values if the data was copied during the resize (which is likely, but not completely certain; a vector may allocate space for more than the needed elements; indeed, when growing it often must do that in order to fulfill the complexity requirements).

You can get the current capacity (number of elements you can grow it to before reallocation is needed) through the member function capacity. As long as the vector doesn't grow beyond the current capacity, even iterators, pointers and references to the stored objects are safe. Also, if you want to make sure that no iterators, pointers or references are invalidated, and you know beforehand the maximal size to which the vector may grow, then you can preallocate all needed memory with the member function reserve.

like image 2
celtschk Avatar answered Oct 10 '22 11:10

celtschk