2010-07-09 30 views
3

J'ai ce morceau de code:faisant référence à un vecteur :: œuvres avant, mais vecteur :: commencer ne pas

cerr << client->inventory.getMisc().front()->getName() << endl; 
vector<itemPtr>::iterator it; 
it = client->inventory.getMisc().begin(); 
cerr << (*it)->getName() << endl; 

Laissez-moi vous expliquer qu'un peu:

client est un tr1::shared_ptr que les points à un objet qui a un membre nommé inventory qui a un membre privé vector<itemPtr> accessible par getMisc(). itemPtr est un typedef pour tr1::shared_ptr<Item>, et getName() renvoie un std::string membre privé de Item.

Essentiellement, client->inventory.getMisc() se résume à std::vector, et j'essaye d'obtenir un itérateur à son premier élément.

Le problème est que la quatrième ligne segfaults. Apparemment, l'itérateur ou le shared_ptr point vers est invalide. J'ai utilisé la première instruction cerr pour tester si le vecteur lui-même était valide, et il imprime comme il se doit, donc je pense que c'est le cas.

Est-ce que je fais quelque chose de mal? Alternativement, que feriez-vous les gars pour déboguer cela?

+2

Rahter que "expliquer un peu" pouvez-vous fournir du code. Les gens sur ce site sont plutôt doués pour comprendre le code et pour comprendre ce que cela signifie. Et c'est beaucoup plus précis qu'une description en anglais. –

Répondre

12

Exactement quelle est la signature de getMisc?

Si vous renvoyez effectivement un std::vector<itemPtr>, vous renvoyez une copie de la liste. Dans ce cas, le premier modèle d'accès fonctionnera (lentement) car la copie temporaire ne sera pas détruite avant la fin de l'exécution de front, date à laquelle le itemPtr lui-même est copié dans un fichier temporaire. La seconde échoue parce qu'après avoir atteint l'itérateur avec begin, le temporaire tombe hors de la portée et est détruit, laissant l'itérateur juste créé suspendu.

+0

Je suppose que c'est un bon débogage psychique. –

+0

@Walter: Belle prise. –

+0

Oui, c'est ce que ça donne. Que devrais-je faire à la place, renvoyer une référence? – Max

1

Que feriez-vous les gars pour déboguer cela?

étape si le code pour voir ce qui est différent sur ce que front() retours et quelles (*it) retours.

+0

J'ai essayé, mais je ne peux pas bien examiner les variables avec gdb. Lorsque j'essaie 'p client-> inventory.getMisc(). Front()', gdb dit 'Il n'y a pas de membre ou de méthode nommée inventory'. Quand j'essaie 'p * it', je vois qu'il contient un' shared_ptr '. Quand j'essaye 'p ** it', gdb dit 'L'un des arguments que vous avez essayé de transmettre à l'opérateur * n'a pas pu être converti en fonction de la fonction'. – Max

0

Etes-vous sûr que le vecteur n'est pas vide? Il est possible que front et begin se comportent légèrement différemment et que front puisse fonctionner par pur hasard, alors que des vérifications supplémentaires dans l'itérateur lui-même provoquent le défaut de seg quand il est utilisé.