OVH Cloud OVH Cloud

iterator, pointeur...

3 réponses
Avatar
Nicolas Aunai
salut,

j'ai un petit programme qui plante, je pense que le plantage vient d'un
truc que je fais mal avec un iterator.

voici mon problème.

soit un objet A constitué :
d'une relation d'ordre.
d'une donnée caractéristique.
d'un tableau de pointeur sur d'autres objets A.

soit un tableau d'objets A.

chaque objet A du tableau, à son tableau constitué de pointeurs sur les
autres objets A (ses voisins), triés selon la relation d'ordre.

A possède entre autres les méthodes suivantes :
MiseAJour, chargée de mettre a jour la liste de pointeurs sur les
voisins de l'objet.
maj, fonction statique mettant a jour tous les objets d'un tableau.


pour illustrer ça, je fais un exemple avec un objet MaString :

class MaString
{
public:
string s; //donnée caractéristique
vector<const MaString *> tab; //liste des voisins

MaString(const string &str, const vector<MaString> & t);
void MiseAJour(const vector<MaString> &t);
static void maj(vector<MaString> &t);
bool operator<(const MaString &ms) const; // relation d'ordre
friend ostream & operator<<(ostream &os,const MaString &ms);
};


voici la définition de la méthode de mise a jour des voisins :


void
MaString::MiseAJour(const vector<MaString> &t)
{
vector<MaString>::const_iterator iter_t = t.begin();
vector<const MaString*>::iterator iter_tab = tab.begin();

while(iter_t != t.end())
{
cout << "DEBUT WHILE" << endl;

if(&*iter_t != this)
{
cout << "&ITER_T!= THIS" << endl;

if(iter_tab == tab.begin())
{
cout << "ITER_TAB == TAB.BEGIN()" << endl;
tab.push_back(&*iter_t);
iter_tab ++;
}
else
{
cout << "ITER_TAB != TAB.BEGIN()" << endl;
if(**(iter_tab-1) < *iter_t) //ICI PLANTAGE
{
cout << "**ITER_TAB < *ITER_T" << endl;
tab.push_back(&*iter_t);
iter_tab ++;
}
else
{
cout << "**ITER_TAB > *ITER_T" << endl;
tab.insert(iter_tab,&*iter_t);
iter_tab ++;
}
}
}
iter_t ++;
}
}


et voici l'affichage que j'ai à l'execution :

DEBUT WHILE
DEBUT WHILE
&ITER_T!= THIS
ITER_TAB == TAB.BEGIN()
DEBUT WHILE
&ITER_T!= THIS
ITER_TAB != TAB.BEGIN()

puis plantage...

le plantage se trouve donc à l'endroit que j'ai commenté "ICI PLANTAGE"
cependant je ne comprends pas pourquoi.


en effet, le premier passage dans la boucle ne fais qu'incrémenter
l'indice dans le tableau 't' car sa première case EST l'objet MaString
(il peut pas etre son propre voisin)

dans le second passage, iter_t à bien été incrémenté, et iter_tab est
toujours au début du tableau de voisin donc on ajoute l'adresse du
voisin dans la première case.
on incrémente ensuite iter_tab
puis on incrémente iter_t

troisième passage dans la boucle
l'adresse est toujours différente de la notre, on continue, iter_tab a
bien été incrémenté, là on regarde la relation d'ordre entre le voisin
présent a la case d'avant et le voisin qu'on veut ajouter, pour savoir
si on doit l'ajouter avant ou après.
c'est pour ça que je fais :

if(**(iter_tab-1) < *iter_t)

c'est ce que j'aurai fait avec des pointeurs, mais avec des iterator...
ça n'a pas l'air de marcher...

j'ai essayé de faire :

if(**(iter_tab-sizeof(MaString*)) < *iter_t)

mais ça plante tout pareil...

si vous voyez où se trouve l'erreur, moi je sèche...

--
Nico,
http://astrosurf.com/nicoastro
messenger : nicolas_aunai@hotmail.com

3 réponses

Avatar
Franck Branjonneau
Nicolas Aunai écrivait:

salut,


Bonjour,

j'ai un petit programme qui plante, je pense que le plantage vient
d'un truc que je fais mal avec un iterator.


Mais peur-être pas...

voici mon problème.
[ Peu clair ]

pour illustrer ça, je fais un exemple avec un objet MaString :

class MaString
{
public:
string s; //donnée caractéristique
vector<const MaString *> tab; //liste des voisins

MaString(const string &str, const vector<MaString> & t);


Plutôt MaString(const std::string & str, const std::vector< MaString * > & t) ?
^^^

void MiseAJour(const vector<MaString> &t);
static void maj(vector<MaString> &t);
bool operator<(const MaString &ms) const; // relation d'ordre
friend ostream & operator<<(ostream &os,const MaString &ms);
};


voici la définition de la méthode de mise a jour des voisins :


void
MaString::MiseAJour(const vector<MaString> &t)
{
vector<MaString>::const_iterator iter_t = t.begin();
vector<const MaString*>::iterator iter_tab = tab.begin();

while(iter_t != t.end())
{
cout << "DEBUT WHILE" << endl;

if(&*iter_t != this)
{
cout << "&ITER_T!= THIS" << endl;

if(iter_tab == tab.begin())
{
cout << "ITER_TAB == TAB.BEGIN()" << endl;
tab.push_back(&*iter_t);
iter_tab ++;
}
else
{
cout << "ITER_TAB != TAB.BEGIN()" << endl;
if(**(iter_tab-1) < *iter_t) //ICI PLANTAGE


Mais encore ? En pariculier, est-ce que MyString::operator< est bien
défini ?

{
cout << "**ITER_TAB < *ITER_T" << endl;
tab.push_back(&*iter_t);
iter_tab ++;
}
else
{
cout << "**ITER_TAB > *ITER_T" << endl;
tab.insert(iter_tab,&*iter_t);
iter_tab ++;
}
}
}
iter_t ++;
}
}


--
Franck Branjonneau

Avatar
Nicolas Aunai


MaString(const string &str, const vector<MaString> & t);


Plutôt MaString(const std::string & str, const std::vector< MaString * > & t)
? ^^^


euh oui...


cout << "ITER_TAB != TAB.BEGIN()" << endl;
if(**(iter_tab-1) < *iter_t) //ICI PLANTAGE


Mais encore ? En pariculier, est-ce que MyString::operator< est bien
défini ?


oui oui il l'est.

en fait l'erreur devait venir du push_back, qui réallouait la mémoire,
les iterator n'étaient plus valides. j'utilise des indices à présent
c'est plus sûr.

--
Nico,
http://astrosurf.com/nicoastro
messenger :


Avatar
Nicolas Aunai
Nicolas Aunai a exposé le 11/02/2004 :


MaString(const string &str, const vector<MaString> & t);


Plutôt MaString(const std::string & str, const std::vector< MaString * > &
t) ?
^^^


euh oui...



euh en fait non non !! :) 't' est le tableau d'objets principal qui
contient l'objet courant et ses voisins

--
Nico,
http://astrosurf.com/nicoastro
messenger :