Reputation: 297
I declared a struct like this, and the following data structures
struct piece{
int start, height, end;
piece(int a, int b, int c){
start = a; height = b; end = c;
}
};
vector<piece> piecesTog;
map <int,piece*> data;
Then, when I read the elements I do this:
while(scanf("%d %d %d", &aux1, &aux2, &aux3) != EOF){
piecesTog.push_back( piece(aux1, aux2, aux3) );
data[a] = data[c] = &piecesTog[tam];
}
Well, until now, I have had no problem. However, later in the program, I have to use the piece* part, to do so, I use an iterator like this
for(map< int, piecesTog* >::iterator it = data.begin(); it != data.end(); it++){
piece* aux = it->second;
...
}
I want to have access to the structure that the it->second points, but I tried everything and nothing worked.
I printed the memory adress of it->second and &piecesTog[tam] and they are the same, but when I do (*aux).height or it->second->height they give number completely crazy, probably some trash.
I have no clue why that is happening.
If anyone has any idea how to fix it, I would appreciate it.
Upvotes: 1
Views: 478
Reputation: 33932
while(scanf("%d %d %d", &aux1, &aux2, &aux3) != EOF){
piecesTog.push_back( piece(aux1, aux2, aux3) );
data[a] = data[c] = &piecesTog[tam];
}
is almost certainly not following the Iterator invalidation rules.
piecesTog.push_back( piece(aux1, aux2, aux3) );
can trigger a resize which typically creates a new datastore, copies the elements from the old data store to the new one and then deletes the old datastore, leaving the pointers cached by
data[a] = data[c] = &piecesTog[tam];
dangling. When you use those pointers some time in the future, Ka-Blammo! Undefined Behaviour and an easily identified crash if you're lucky.
Insufficient information has been provided to supply a definitive solution, but here are a few general alternatives (in order of attractiveness):
If you know ahead of time the number of piece
s that will go into piecesTog
, you can reserve
storage to eliminate the need to resize the vector
.
If elements are only added to the end of the vector
and no elements are ever removed, you can store the indexes of the elements rather than pointers to them. If the ordering never changes, the indexes will always refer to the correct elements no matter how many more items are added.
If it is possible to do so, rewrite the reader to load all of the pieces
into piecesTog
and then build the maps.
The above options all assume that piecesTog
is assembled all at once and then left alone. If your insertion is more free-form, you sort the structure or you remove elements, you'll need to use a data structure with more favourable invalidation rules such as std::list
.
Upvotes: 3