2010-12-04 44 views
0

J'ai vérifié ce code considérablement maintenant et je me suis assuré que je produis les choses 'correctes' pour décrire le problème. L'itérateur ne pointe jamais du tout sur la liste, mais un autre groupe d'adresses qui contiennent heureusement les données correctes.Les problèmes d'itérateur continuent

J'ai deux questions:

1 = étant donné la forme des Couts, suis-je fournir en sortie les éléments corrects pour enquêter sur la raison pour laquelle cette boucle ne sort pas;

2 = si (1), alors ce qui se passe pour produire cette sortie et avez-vous des conseils à approfondir mes connaissances de pointeur (j'ai utilisé ce pour le format de boucle plusieurs fois avant et ce que n'est jamais arrivé,

/questions

Code

:

#include "neutronFileReader.h" 

using namespace std ; 

neutronFileReader::neutronFileReader() 
{ 
} 

list<vector<float> > neutronFileReader::spectrum(char* filename) 
{ 
ofstream addresses ; 
addresses.open("adresses.txt") ; 
ifstream fin(filename) ; 
string binhi, binlo ; 
list<vector<float> > neutronSpectrum ; 
list<vector<float> >::iterator nS ; 
vector<float> EnergyProbability ; 

while(!fin.eof()) 
{ 
    EnergyProbability.clear() ; 
    getline(fin, binlo, ' ') ;  //get the binlo string 
    getline(fin, binhi, ' ') ;  //get the binhi string 

    EnergyProbability.push_back(atof(binhi.c_str())+(atof(binhi.c_str()) - atof(binlo.c_str()))/2) ; //store middle of bin as emission Energy 

    getline(fin, binlo) ;  //try not to waste memory space 

    EnergyProbability.push_back(atof(binlo.c_str())) ; //store emnission probability 
    neutronSpectrum.push_back(EnergyProbability) ; //put the vector in the list 
} 

for(nS = neutronSpectrum.begin() ; nS != neutronSpectrum.end() ; nS++) //go through the neutron spectrum 
{ 
    EnergyProbability = (*nS) ; 
    addresses << &neutronSpectrum.begin() << " : " << &(*nS) << " : " << &neutronSpectrum.end() << endl ; // print energy & prob to screen 
    cout << &neutronSpectrum.begin() << " : " << &(*nS) << " : " << &neutronSpectrum.end() << endl ; 
} 

return neutronSpectrum ; 
} 

et est ici la sortie:

0x28fbc4 : 0x510c38 : 0x28fbc0 
0x28fbc4 : 0x510c58 : 0x28fbc0 
0x28fbc4 : 0x510c78 : 0x28fbc0 
0x28fbc4 : 0x510c98 : 0x28fbc0 
0x28fbc4 : 0x510cb8 : 0x28fbc0 
0x28fbc4 : 0x510cd8 : 0x28fbc0 
0x28fbc4 : 0x510cf8 : 0x28fbc0 
0x28fbc4 : 0x510d18 : 0x28fbc0 
0x28fbc4 : 0x510d38 : 0x28fbc0 
0x28fbc4 : 0x510d58 : 0x28fbc0 
0x28fbc4 : 0x510d78 : 0x28fbc0 
0x28fbc4 : 0x510d98 : 0x28fbc0 
0x28fbc4 : 0x510db8 : 0x28fbc0 
0x28fbc4 : 0x510dd8 : 0x28fbc0 
0x28fbc4 : 0x510df8 : 0x28fbc0 
0x28fbc4 : 0x510e18 : 0x28fbc0 
0x28fbc4 : 0x510e38 : 0x28fbc0 
0x28fbc4 : 0x510e58 : 0x28fbc0 
0x28fbc4 : 0x510e78 : 0x28fbc0 
0x28fbc4 : 0x510e98 : 0x28fbc0 
0x28fbc4 : 0x510eb8 : 0x28fbc0 

merci beaucoup.

Répondre

0

Ok, il semble fonctionner alors (selon le dernier exemple).

Il atteint le dernier élément puis s'arrête (ceux avec le moment n'atteignent jamais le dernier élément car ils échouent la condition sur le dernier élément).

La clé ici est que .end() et .back() pointent vers des choses différentes de sorte que la différence d'adresses est à prévoir.

.back() fait référence au dernier élément de la liste. .end() fait référence à un passé-dernier élément qui sert à arrêter le cycle seulement après le dernier élément a été traité (par opposition à ce qui se passe avec le:

while(&(*nS) != lastListElement) { 
/*...* 
} 

qui se traduit par l'arrêt du cycle avant d'analyser la dernier élément.

d'après ce que je pouvais recueillir votre seul problème était avec la sortie des adresses droite? Ou est le cycle ne sortant où il est censé?

+0

Ce n'était pas, maintenant c'est grâce à votre aide, en fait, il se comportait correctement après un poste. * embarassé. Cependant ce va-et-vient a grandement amélioré ma compréhension des itérateurs alors merci TRES Révolte, je suis désolé de perdre votre temps. J'espère que vous en avez aussi quelque chose! – morb

+0

En effet! La dernière fois que j'ai joué avec des conteneurs STL (la dernière fois que j'ai joué avec C++) c'était il y a 2 ans, donc ça a servi de rappel. Content que je puisse être utile! – AlexJF

1

Corrigez-moi si je me trompe mais les 1ère et 3ème colonnes ne représentent-elles pas les pointeurs vers les instances d'itérateur retournées par begin() et end() plutôt que par les pointeurs vers les objets (de la liste)?

+0

+1 vous êtes tout à fait raison –

+0

qui est grande information , merci! Changer de code maintenant, mais comment? Remplacer par: & (* neutronSpectrum.begin()) est-ce correct? Le comportement du pointeur arning est une tâche difficile (lorsque vous essayez d'écrire du vrai code en même temps) :) – morb

+0

Je suppose que votre solution & (neutronSpectrum.begin()) est en effet la bonne approche.Il déréférencerait l'itérateur renvoyant l'élément vers lequel il pointe, puis vous obtiendriez son adresse mémoire en utilisant l'opérateur &. – AlexJF

0

Je viens de le découvrir moi-même mais il semble que l'itérateur renvoyé par list.end() ne pointe pas vers un élément valide. Il pointe vers l'élément passé-la-fin.

Afin que nous puissions comprendre correctement ce qui se passe, vous devez afficher list.back() qui pointe effectivement vers le dernier élément de la liste. Notez que list.back() ne renvoie pas d'itérateur mais une référence directe au dernier élément (vous devriez donc simplement imprimer ce qui est renvoyé sans déréférencement).

+0

Oui, vous avez raison. Dès que j'ai posté le ci-dessous j'ai commencé à jouer avec la méthode .back(). Malheureusement, je ne peux pas dire à l'itérateur d'y mettre fin. – morb

+0

Oui, vous avez raison. Dès que j'ai posté le ci-dessous j'ai commencé à jouer avec la méthode .back(). Malheureusement, je ne peux pas dire à l'itérateur d'y mettre fin. J'ai essayé différents fiddles mais le même résultat à chaque fois: C: \ Utilisateurs \ morb \ Documents \ Programmation \ C++ \ collimatedNeutrons \ neutronFileReader.cpp: 35: erreur: aucune correspondance pour 'operator! =' Dans 'nS! = LastListElement', et similaire (remplacer lastListElement par une variété de tentatives) Y at-il un moyen de le faire? En ce moment, je vais supprimer entièrement l'itérateur et essayer d'utiliser un pointeur normal pour parcourir la liste. - Cela n'a pas marché – morb

+0

J'ai seulement suggéré .back() à des fins de débogage (pour le cout). Je ne recommanderais pas vraiment de l'utiliser pour la boucle for, mais si vous voulez vraiment l'essayer, vous devrez l'utiliser comme ceci: for (...; & (* nS)! = LastListElement; ...). Ceci bien sûr supposant que lastListElement est le pointeur vers le dernier élément de la liste. – AlexJF