Reputation: 4338
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
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
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
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
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