2016-07-07 2 views
0

Mon code tombe en panne de temps en temps à cause de lastd :: corruption de mémoire lors de l'utilisation deque iterator pour effacer les éléments

suivante
//queue is a std::shared_ptr<std::deque<Something> > 
//I can guarantee that queue will never be empty. 
std::deque<Something>::iterator it = queue->end(); 
it--; 
queue->erase(it); 

Pas toujours, mais parfois. Cela arrive surtout après avoir ajouté quelque chose à l'avant puis essayer de supprimer le dos.

Si je change à

queue->pop_back(); 

à bail ont pas vu écraser depuis longtemps.

Mais quelqu'un peut-il m'éclairer pourquoi l'ancien code va planter? Je suppose que c'est quelque chose lié au fait que le redimensionnement peut invalider tous les itérateurs. Mais ce que j'ai fait était -- pas ++.

Quelqu'un peut-il m'expliquer pourquoi?

// -----------------------

// Mise à jour

// -------- ---------------

Ma compréhension est it est juste un pointeur. Il n'y a pas d'insertion, entre obtenir it et utiliser it.

La seule opération est it--. Mais puisque it-- est un pointeur en mouvement. Nous faisons toujours

for(it = xxx.begin(); it!=xxx.end(); ++it) 
{ 
    ... 
} 

Cela fonctionne très bien. Ou est-ce illégal suivant? Ce que je ne comprends pas, c'est pourquoi un pointeur se déplaçant dans la plage valide provoquera une corruption de la mémoire. Comme , it indique l'élément exact que je veux, il n'y a aucun moyen de récupérer ce pointeur à moins que j'utilise simplement (xxx.end()-1) à la place.

Merci

+0

double possible de [pour la recherche et la suppression de certains éléments à l'aide std :: deque :: iterator (dans la STL de C)] (http://stackoverflow.com/ questions/15490219/using-stddequeiterator-in-c-stl-for-search-and-deleting-certain-eleme) –

+0

@ChrisMorgan: cela ne semble pas être le même problème, à moins qu'il n'utilise aussi 'it' après le 'effacer '. –

+0

@MatteoItalia J'ai supposé qu'il y avait plus de code qui l'a réutilisé, puisque les 3 lignes données sont légitimes tant que le commentaire sur la file d'attente non-vide est vrai. –

Répondre

0

Si votre file d'attente n'est pas vide - tout va bien avec votre code.

Votre déclaration sur itérer inverse

for(it=xxx.end();it!=xxx.begin();--it){...} 

peut être illégale dans le cas si vous manipuler iterator dans le corps de la boucle. Le déréférencement xxx.end() peut entraîner une erreur de segmentation. Dans ce cas, il est préférable d'utiliser itérateurs inverse:

for(it=xxx.rbegin();it!=xxx.rend();++it){...}