|
noob4ever
|
Posté le 29 Août 2008 à 11:34
|
|

Messages : 295
GCPoints : 48742
|
Ah oui là ok .
What did C:/DARTHVADER said to C:/DARTHVADER/LUKESKYWALKER ?
I'm your folder
|
|
Mod
|
Posté le 07 Sep 2008 à 18:57
|
|

Messages : 4954
GCPoints : 2100823
|
Allez, un autre que j'oublie deux fois sur trois : initialiser de fond en comble une structure à sa création.
Exemple dans mon cas : je créé un nouveau processus depuis une application parente. Processus qui doit utiliser DirectX, et donc créer une fenêtre pour y attacher l'objet Direct3D.
Problème : mon application créait bien la fenêtre (mais ne l'affichait pas), et l'initialisation Direct3D ne fonctionnait pas. Le tout sans retourner d'erreurs.
Solution : un petit coup de ZeroMemory sur la structure utilisée pour créer le processus, et hop, problème résolu .
|
|
Darktib
|
Posté le 07 Sep 2008 à 20:10
|
|

Messages : 4017
GCPoints : 347288
|
Ah, actuellement j'ai un bug plutot cocasse...
J'ai un vector nommé childs (pour le compilo de mon langage de scripts) de pointeurs...
A un moment, j'appelle une fonction qui est sensée appeler cette meme fonction mais chez tous les enfants (childs) puis effectuer ce quelle a a faire. Il y a un objet dans le tableau, je peut faire childs[0] (la méthode size() et tout le reste sont unanimes dessus...). Et bah manque de bol, je recois une segfault pour l'operateur []...
A détecter c'est facile... a résoudre... un peu moins... (d'ailleurs je ne l'ai pas toujours résolu^^ et j'espere le faire vite...)
Autant les strings de la stl c'est bien, mais les vectors ne valent pas ceux d'irrlicht je trouve
|
|
SEB
|
Posté le 08 Sep 2008 à 15:28
|
|

Messages : 554
GCPoints : 103313
|
Citation :Il y a un objet dans le tableau, je peut faire childs[0]
et alors? faire child de 0 ne veut pas dire qu'il y a un objet dedan surtout si comme tu l'as dit c'est un vector de pointeur....
il faudrait donc 1 que tu vérifie si les contenu ne sont pas NULL et ensuite mem si il ne sont pas nuls... que tes pointeurs d'objets ne sont pas obsolètes... Tu peu toujours résoudre ça en utilisant des smart pointers... mais personnellement j'aime pas trop ca lool ^^
Voilou voilou
++
Seb
NextGine : 3D games engine
Nombre de lignes actuel : 77683
|
|
Darktib
|
Posté le 08 Sep 2008 à 20:08
|
|

Messages : 4017
GCPoints : 347288
|
bug résolu...
En fait, dans cette fonction je vérifie toujours les tableaux et tout ce qui est dans le vérifiable vu que je n'ai pas la performance pour objectif.
Citation :si les contenu ne sont pas NULL et ensuite mem si il ne sont pas nuls... que tes pointeurs d'objets ne sont pas obsolètes
Ca c'est toujours vérifié, les conditions étant vraies.
Cela dit, mon bug s'est déplacé... c'était un petit vicieux en fait
Du coup j'ai un pointeur sur une classe... avec ce pointeur je peux récuperer les attributs publics mais pas appeler les methodes publiques... (encore des segfault...^^)
|
|
SEB
|
Posté le 08 Sep 2008 à 21:32
|
|

Messages : 554
GCPoints : 103313
|
Est-ce que c'est une sous classe d'une hiérarchie? contenant par exemple des attributs dans une classe mère etc...???
NextGine : 3D games engine
Nombre de lignes actuel : 77683
|
|
Darktib
|
Posté le 09 Sep 2008 à 18:21
|
|

Messages : 4017
GCPoints : 347288
|
Voici la classe (un peu spéciale^^ - et j'ai changé le nom et simplifié la classe)
Code :
class myClass
{
public:
ctor;
dtor;
//fonctions
// la fonction qui plante :
virtual void recomputeOffset
{
for(unsigned int t = 0; t < childs.size(); t++)
{
childs[t]->recomputeOffset();
}
if(parent == 0)
{
offsetToParent = 0;
}
else
{
// Voila la ligne qui plante. L'appel de fonction déconne mais pas l'appel d'attribut...
offsetToParent = parent->totalChilds(parent->childNum)+1;
}
}
// un autre fonction
virtual unsigned int totalChilds(unsigned int from)
{
int offset = 0;
if(childs.size() == 0) return 0;
for(unsigned int t = from; t < childs.size(); t++)
{
offset += childs[t]->totalChilds(0);
offset++;
}
}
//attributs
myClass* parent;
std::vector<myClass*> childs;
unsigned int offsetToParent;
unsigned int childNum;
};
Voila en gros ma classe.
A noter que ce code n'est pas destiné a etre publié, du coup je respecte moins les regles d'encapsulation.
Dernière édition le 09 Sep 2008 à 18:21
|
|
dstar
|
Posté le 10 Sep 2008 à 08:48
|
|

Messages : 56
GCPoints : 25718
|
Mouais...
Peut-être faudrait-il commencer par écrire un code correct:
- ton opération recomputeOffset n'a pas de liste de paramètres,
- ton opération totalChilds déclare retoruner un unsigned int mais ne possède pas d'instruction return à la fin, sauf dans le cas où il n'y a pas de fils.
dstar
dstar
|
|
Darktib
|
Posté le 10 Sep 2008 à 15:44
|
|

Messages : 4017
GCPoints : 347288
|
pour le totalChilds c'est une erreur de recopiage, normalement elle retourne bien un unsigned int^^
Et sinon pourquoi des parametres pour recomputeOffset? Vu que ca calcule l'offset de la class en cours normalement les parametres seraient superflus...
Ah tu veux des parametres pour le parent... *vient de comprendre ^^*
mouais...
Je peux toujours essayer^^
Dernière édition le 10 Sep 2008 à 15:45
|
|
dstar
|
Posté le 10 Sep 2008 à 18:21
|
|

Messages : 56
GCPoints : 25718
|
Citation :Et sinon pourquoi des parametres pour recomputeOffset? Vu que ca calcule l'offset de la class en cours normalement les parametres seraient superflus...
Ah tu veux des parametres pour le parent... *vient de comprendre ^^*
mouais...
Euh non, ce n'est pas ce que je voulais dire... en général, quand une opération ne possède pas de paramètre, on met quand même une liste vide (). Mais ce n'est certainement pas la cause de ton bug.
J'ai relu tes posts précédents et je vois que tu parles d'un segmentation fault. En général, sur les systèmes Unix (dont Linux), un segmentation fault est synonyme d'un pointeur NULL. Et le bus error induit l'utilisation d'une adresse mémoire invalide (hors espace d'adressage).
dstar
dstar
|
|
Darktib
|
Posté le 10 Sep 2008 à 19:46
|
|

Messages : 4017
GCPoints : 347288
|
En fait tu m'a mis sur la voie... j'ai mis le parent en parametre et maintenant ca marche nickel - donc merci pour ton aide - et ma scepticité ne m'a servie a rien^^.
Sinon je suis sous Windows pour les tests... mais normalement mais librairie devrait etre portable.
Eu Citation :h non, ce n'est pas ce que je voulais dire... en général, quand une opération ne possède pas de paramètre, on met quand même une liste vide (). Mais ce n'est certainement pas la cause de ton bug.
Le 'on' qui rajoute la liste vide, c'est nous ou le compilateur? Et qu'est-ce que la liste vide en question?
Sinon pour la segfault, le pointeur a NULL est aussi vrai pour windows; mais en plus -je ne suis pas sur- il me semble que la segfault sur windows englobe aussi le bus error de linux.
Mais ce que par contre je ne comprend pas c'est que ca plantait que pour les méthodes et pas les attributs...
|
|
dstar
|
Posté le 11 Sep 2008 à 10:07
|
|

Messages : 56
GCPoints : 25718
|
Citation :Le 'on' qui rajoute la liste vide, c'est nous ou le compilateur? Et qu'est-ce que la liste vide en question?
Le 'on', c'est le stanard ANSI C++. Quand une fonction C++ (qu'elle soit membre de classe ou non) ne prend pas de paramètre, on se doit de mettre, après le nom de la fonction, une parenthèse ouverte suivie d'une parenthèse fermée. Il est possible d'ajouter le mot clef void, ça sert pour la compatibilité avec le C.
Mais en aucun, le standard ne permet de déclarer une fonction en écrivant le nom et en ouvrant directement le corps de la fonction, comme tu l'as fait avec ta fonction recomputeOffset.
Tu as écrit:
Code :
void recomputeOffset
{
...
}
là où tu aurais dû écrire:
Code :
void recomputeOffset()
{
...
}
ou à la limite:
Code :
void recomputeOffset(void)
{
...
}
Certains compilateurs l'acceptent, mais ce n'est pas standard. Dans tous les cas, ce n'est certainement pas la cause de ton bug.
D'après ce que tu décris, c'est probablement le membre parent de ta classe qui possédait une valeur erronnée quand l'opération recomputeOffset était appelée.
dstar
dstar
|
|
Darktib
|
Posté le 11 Sep 2008 à 21:07
|
|

Messages : 4017
GCPoints : 347288
|
ah je vois ce que tu veux dire... pour l'histoire des parametres c'est une erreur de copie, jamais gcc n'accepterait un truc pareil^^
Sinon pour la valeur erronée... c'est a mon avis ce qui s'est passé. Mais je ne comprend toujours pas le bug : il n'arrivait que lorsque le fait d'avoir des enfants se reproduisait + de 2 fois, et uniquement quand la fonction n'avait pas de grands-parents... et evidemment que pour les méthodes...
Finalement je penche pour peut etre une erreur compilo.
|
|
dstar
|
Posté le 12 Sep 2008 à 09:12
|
|

Messages : 56
GCPoints : 25718
|
Citation :Finalement je penche pour peut etre une erreur compilo.
, je parie ce que tu veux que ce n'est pas un problème de compilateur. Les erreurs de compilateurs C++, ça n'existe pratiquement plus aujourd'hui, enfin, sauf si tu utilises un outil exotique.
dstar
dstar
|
|
Mod
|
Posté le 12 Sep 2008 à 14:07
|
|

Messages : 4954
GCPoints : 2100823
|
Hum, en effet, des bugs de compilateur C ou C++, faut vraiment les chercher. Car heureusement pour nous, tout le monde n'est pas de chez TGC.
|
|
Darktib
|
Posté le 12 Sep 2008 à 19:59
|
|

Messages : 4017
GCPoints : 347288
|
Ben gcc m'avait quand meme généré une dll trop grosse a mes débuts d'IA::Astar - ce qui la ralentissait considérablement.
Ensuite est-ce que vous pouvez expliquer en s'appuyant sur le standard ISO C++ pourqoi avec le meme pointeur on ne peut appeller que les attributs et pas les méthodes???
Sans réponse, j'ai choisi l'option la plus facile . L'autre - erreur humaine - me parait improbable ( ).
edit : :je viens d'exploser mes statistiques en matiere de smiley lol dans un message^^
Dernière édition le 12 Sep 2008 à 20:00
|
|
dstar
|
Posté le 12 Sep 2008 à 23:35
|
|

Messages : 56
GCPoints : 25718
|
Citation :Ensuite est-ce que vous pouvez expliquer en s'appuyant sur le standard ISO C++ pourqoi avec le meme pointeur on ne peut appeller que les attributs et pas les méthodes???
Bon, j'explique.
Dans le cas d'un attribut, l'adresse de l'attribut par rapport à l'adresse de base de l'objet est constante. Ca signifie qu'à partir de l'adresse de l'objet, le compilateur met en place un calcul simple (une addition) pour calculer l'adresse de l'attribut.
Dans le cas d'une méthode virtuelle appelée à partir d'un pointeur ou d'une référence, c'est bien plus compliqué (ce n'est pas le cas pour les méthodes qui ne sont pas virtuelles). Ceci vient du fait que le compilateur doit mettre en place une liaison dynamique.
En effet, le type réel d'un objet peut être différent du type du pointeur ou de la référence servant à référencer l'objet, ça s'appelle le polymorphisme d'objet. L'adresse de la méthode C++ à appeler est dépendante du type réel de l'objet et non du type du pointeur ou de la référence utilisée pour faire l'appel. Et le compilateur ne peut connaître, au moment de la compilation l'adresse de la méthode à appeler.
Une liaison dynamique consiste pour le compilateur à mettre un descripteur de classe, pour chaque classe, qui contient l'adresse des méthodes virtuelles. Lors de l'appel à une fonction virtuelle, au lieu de sauter directement à l'adresse de la méthode, l'application doit d'abord accéder à ce descripteur pour déterminer l'adresse à laquelle sauter (en général, l'adresse du descripteur de la classe d'un objet est stockée 4 octets avant l'adresse de base de l'objet).
Dans le cas où une application possède un bug qui corrompt une partie de la mémoire, il est possible que le descripteur d'une classe soit affectée sans que la valeur des attributs de ses instances ne le soient.
dstar
dstar
|
|
Darktib
|
Posté le 13 Sep 2008 à 18:23
|
|

Messages : 4017
GCPoints : 347288
|
Merci pour l'explication ( qui d'ailleurs a l'avantage d'etre tres claire).
Donc ca voudrait dire que le descripteur de la classe est modifié... peut etre alors parce ce que cette classe "s'appelle" soit-meme. C'est ballot.
Donc comme ca la prochaine fois je mettrait des pointeurs en arguments^^
je me coucherait moins bete ce soir
|