Invictus
Invictus

Reputation: 4338

Why doesn't C++ take care of iterators when insertion is done in a vector after capacity is reached?

I wrote this small code just to see how an iterator actually gets invalidated and does not point to changed location of a vector after its capacity is reached.

Here the size of vector and capacity is both 5 initially . After that I inserted a few other elements in vector and does not re-initialize my iterator to point to myvector.begin(). This lead to a junk value of 49 in my output after maximum size of vector is : 1073741823 when printing elements of vector again.

My question is why C++ does not make point iterator again to a valid myvector.begin() after all elements are copied into new location?
This can also lead to some behavior which can be hard to debug. I know a safe way to work would be to always reinitialize the iterator just before using it.

  #include<iostream>
  #include<vector>
  #include<stdio.h>

  using namespace std;

  int main()
  {
    vector<int> myvector;
    vector<int>::iterator it;
    int myarray[]= {100,200,300,400};
    myvector.insert(it,500);
    it=myvector.begin();
    myvector.insert(it,myarray,myarray+4);
    it=myvector.begin();
    for(;it!=myvector.end();++it)
    cout <<*it<<endl;
    cout <<"size of vector is :" << myvector.size() <<"\n"; 
    cout <<"capacity of vector is : " << myvector.capacity()<<"\n";  
    cout <<"maximum size of vector is : " << myvector.max_size()<<"\n"; 
    myvector.push_back(600);
    for(;it!=myvector.end();++it)
    cout <<*it<<endl;
  }
  Output of program :-
  100
  200
  300
  400
  500
  size of vector is :5
  capacity of vector is : 5
  maximum size of vector is : 1073741823
  49
  100
  200
  300
  400
  500
  600

Upvotes: 5

Views: 430

Answers (4)

MSalters
MSalters

Reputation: 179907

The STL didn't try to implement all possible containers. While your container design is certainly possible, it's just not included. std::vector<T> seems similar, but it tries to be a better array than T[] with little overhead. That goal isn't directly compatible with yours.

Luckily, the STL design is modular, so even if you did write your own container to act like this, you can still reuse all the STL algorithms, as well as STL-compatible algorithms (e.g. those in boost).

Upvotes: 1

Ed Swangren
Ed Swangren

Reputation: 124692

The iterator is not tied to the vector in any meaningful way (how could it be implemented as a pointer if it were?). The vector doesn't know about the iterator. It is your job to not use an invalid iterator.

So you propose adding a ton of complexity to the vector class for... what purpose exactly? How does this solve problems in the real world where we know that doing such a thing is a bad idea?

Upvotes: 4

pmdj
pmdj

Reputation: 23438

Presumably because the vector would have to keep track of a list of all its iterators and notify them all when they become invalid. This would introduce rather a lot of overhead. The STL containers' operations all have very well-specified invalidation rules, you just have to follow them as the programmer.

Note that as per the standard, you can't rely on vector iterators being valid at all after insertion or deletion. That it still worked for you until resizing is an implementation detail.

Upvotes: 3

Luchian Grigore
Luchian Grigore

Reputation: 258618

Because it's impractical, and probably impossible.

Is the vector supposed to keep a list of all its iterators and them modify all of them as soon as an invalide-triggering method is called?

Upvotes: 9

Related Questions