Segmentation Fault

Segmentation Fault - C++ - Programmation

Marsh Posté le 20-12-2006 à 11:52:18    

Bonjour
 
comme l'indique le titre, j'ai un problème d'erreur de segmentation que je ne comprends pas:
 
ça, c'est unité.cpp, c'est à ce moment qu'il va y avoir l'erreur

Code :
  1. if(! (categorie & BATIMENT))
  2.     {
  3.       cout<<"on avance"<<endl;
  4.       position.afficher();
  5.       actions.push_back(new ActionAVANCER(this,position));
  6.     }


actions est un vector de Action*
 
 
ça, c'est le constructeur de ActionAVANCER:

Code :
  1. ActionAVANCER::ActionAVANCER(Unite *unit,Point& destination):Action(unit),destination(destination)
  2. {
  3.   cout<<"création d'une actionAVANCER"<<endl;
  4.   antiBlocage.x=0;
  5.   antiBlocage.y=1;
  6.   antiBlocage.z=0;
  7.   derniereCaseBloquage=-1;
  8.   derniereUniteBlocage=NULL;
  9.   dureeVie=0;
  10.   cout<<"je suis: "<<unit->getNom()<<"  et je vais: ";
  11.   destination.afficher();
  12.   cout<<endl;
  13.  
  14. }


 
et ça, c'est le constructeur de Action, la classe abstraite mère de ActionAVANCER:

Code :
  1. Action(Unite *unit):unit(unit){cout<<"Création d'une action"<<endl;}


 
 
donc quand ça marche (oui parceque des fois ça marche... mais c'est plutôt aléatoire)
j'ai comme résultat dans ma console:
 
on avance
x: 45.86    y: 21.26     z: 0
Création d'une action
création d'une actionAVANCER
je suis: commandeur  et je vais: x: 45.86    y: 21.26     z: 0
 
normal...
 
quand ça bloque j'ai:
on avance
x: 43.7    y: 16.58     z: 0
Fatal signal: Segmentation Fault (SDL Parachute Deployed)
 
donc on dirait que le constructeur n'est jamais appelé puisqu'il n'affiche même pas les phrases de test...
 
si vous avez une idée pour me débloquer, merci d'avance...


---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 20-12-2006 à 11:52:18   

Reply

Marsh Posté le 20-12-2006 à 13:31:58    

Citation :

Code :
  1. categorie & BATIMENT


c'est louche, ça... Qu'est-ce que tu voulais faire exactement ? Que sont catégorie et BATIMENT ?
 
Sinon, tu devrais faire tes impressions de debug avec cerr plutôt que cout


---------------
TriScale innov
Reply

Marsh Posté le 20-12-2006 à 18:27:00    

franceso a écrit :

Citation :

Code :
  1. categorie & BATIMENT


c'est louche, ça... Qu'est-ce que tu voulais faire exactement ? Que sont catégorie et BATIMENT ?


On dirait des flags, tout simplement .... du genre, en C :

Code :
  1. #define BATIMENT    0x01
  2. #define BREAKABLE   0x02
  3. #define TARGETABLE 0x04


 
Donc apres tu fais un "ou" logique pour appliquer le flag, et un "et" logique pour le tester. Si ca n'est pas clair, convertit les constantes ci dessus en binaire et tu comprendras :D
 
 
Quant a la segfault, tu devrais initialiser la SDL comme ca :

Code :
  1. SDL_Init(/* flags a toi */ | SDL_INIT_NOPARACHUTE);


 
Et apres tu recuperes l'erreur avec gdb ou visual studio, et tu nous indique la ligne exacte qui fait planter.

Reply

Marsh Posté le 20-12-2006 à 18:53:49    

Pour ce qui est de ma catégorie, c'est exactement ce que j'ai fait, en fait je ne vois pas d'autres moyens de le faire. Ca permet de savoir si une unité est mobile ou non, si elle peut en construire d'autres, en réparer, attaquer...
 
Bon sinon je vais initialiser la SDL comme Ace17 me l'a dit, d'autant plus que je ne sais pas ce que c'est le parachute de la sdl.
 
Je ne sais pas non plus ce que sont gdb et visual studio.
je suis sous linux (debian sarge), ca  peut être utile de le préciser.
 
Oui je devrais utiliser cerr, mais l'habitude de taper cout... dsl

Reply

Marsh Posté le 20-12-2006 à 20:27:36    

ptitchep a écrit :

Pour ce qui est de ma catégorie, c'est exactement ce que j'ai fait, en fait je ne vois pas d'autres moyens de le faire. Ca permet de savoir si une unité est mobile ou non, si elle peut en construire d'autres, en réparer, attaquer...
 


un enum ?

Reply

Marsh Posté le 20-12-2006 à 20:54:55    

Bon alors j'explique pour gdb. C'est tout simplement un debogueur sous Linux. Son emploi te permettra de trouver la ligne qui a génere la segfault. Sinon tu peux également farcir ton programme de cout/printf pour essayer de trouver ou elle se trouve, mais avec gdb c'est plus rapide et plus simple.
 
En gros, voici comment se servir de gdb :
gdb ./monprogramme
run
Et maintenant, pour peu que tu aies compile ton code avec l'information de deboguage (-g3 pour gcc) gdb t'affiche la ligne qui pose probleme.
 
Le parachute SDL maintenant. C'est un mecanisme qui récupere les exceptions au lieu de les renvoyer a l'OS. Ce qui fait que si tu le laisses ce mecanisme actif, les exceptions ne remonteront pas jusqu'a gdb et donc tu ne pourras pas trouver la segfault aussi facilement que decrit ci-dessus.
 
 
Tu ne nous donne pas assez de code pour pouvoir déterminer ce qui y pose probleme. Deja, trouve le moment exact ou ca plante. Ensuite on remontera jusqu'a l'erreur, si besoin.


Message édité par Ace17 le 20-12-2006 à 20:55:57
Reply

Marsh Posté le 20-12-2006 à 21:19:08    

ok je vais essayer merci! :)
 
Le problème c'est que en enlevant le parachute et en recompilant, mon bug a lieu beaucoup moins souvent. Je n'y comprends vraiment rien... Il apparait vraiment sans raison apparente une fois de temps en temps...

Reply

Marsh Posté le 20-12-2006 à 21:19:54    

je suppose qu'il vaut mieux enlever ces informations de deboguage pour la version finale du programme... Ca ralentit non?

Reply

Marsh Posté le 21-12-2006 à 09:05:55    

Eh bien fais donc l'essai :-)
Et balance nous plus de code si tu veux qu'on t'aide.

Reply

Marsh Posté le 21-12-2006 à 11:19:12    

Bon je vais continuer mes tests mais comme je suis pas là pendant les vacances, ça risque d'attendre début janvier.
C'est bien gentil de vouloir plus de code, mais je vous ai filé ce qui plante (d'après mes cout), sinon, la commande
cat -b *pp
m'indique que j'ai 3912 lignes de code... Alors je ne sais pas trop quoi vous donner.

Reply

Marsh Posté le 21-12-2006 à 11:19:12   

Reply

Marsh Posté le 21-12-2006 à 11:27:32    

ptitchep a écrit :

Bon je vais continuer mes tests mais comme je suis pas là pendant les vacances, ça risque d'attendre début janvier.
C'est bien gentil de vouloir plus de code, mais je vous ai filé ce qui plante (d'après mes cout), sinon, la commande
cat -b *pp
m'indique que j'ai 3912 lignes de code... Alors je ne sais pas trop quoi vous donner.


 
oué enfin si tu fais :
cout "toto" ;
int i = 42;
cout "toto2";
et que ca segfault entre les 2 cout, tu ne peux absolument pas conclure que ca vient du "int i = 42". Un débuggeur t'indiquera ce qui merde vraiment :o


---------------
Il y a autant d'atomes d'oxygène dans une molécule d'eau que d'étoiles dans le système solaire.
Reply

Marsh Posté le 21-12-2006 à 11:34:17    

ah ouais?
ça a toujours marché pour moi. Mais c'est vrai qu'avant, quand je développais sous windows, j'avais toujours un debuggeur et c'est vraiment pratique. Je ne connaissait pas gdb, je n'avais que strace qui n'indique que les appels aux fonctions système. J'avoue que ça manque cruellement de recherche cette histoire de debugger!
J'ai plus qu'a bosser le man! :D


---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 21-12-2006 à 13:59:19    

Ace17 a écrit :

On dirait des flags, tout simplement .... du genre, en C :

C'est bien ce que j'avais compris, mais je préfère poser la question quand même : il est ultra courant de voir de gens confondre && et & en C ou C++
 
 
+1 pour gdb.
 
Si tu as l'habitude d'utiliser emacs, il y a un mode gdb qui te permet de visualiser en parallèle le code exécuté et la fenêtre gdb. Pour ça, plutôt que de taper directement "gdb prog" en ligne de commande, tu ouvres un emacs et tu tapes "M-x gdb".


---------------
TriScale innov
Reply

Marsh Posté le 21-12-2006 à 14:04:42    

franceso a écrit :


Si tu as l'habitude d'utiliser emacs, il y a un mode gdb qui te permet de visualiser en parallèle le code exécuté et la fenêtre gdb. Pour ça, plutôt que de taper directement "gdb prog" en ligne de commande, tu ouvres un emacs et tu tapes "M-x gdb".


 
parfait :)


---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 21-12-2006 à 17:20:17    

ptitchep a écrit :

ah ouais? ça a toujours marché pour moi.


 
Exemple amusant :
 

Code :
  1. class SuperTableau
  2. {
  3.    public:
  4.       SuperTableau()
  5.       {
  6.          m_Tab = NULL;
  7.       }
  8.       ~SuperTableau()
  9.       {
  10.          if(m_Tab)
  11.             delete [] m_Tab;
  12.       }
  13.       void Resize(int n)
  14.       {
  15.          if(m_Tab)
  16.             delete [] m_Tab;
  17.          m_Tab = new int[n];
  18.       }
  19.       // accesseurs et compagnie ....
  20.    private:
  21.       int* m_Tab;
  22. };
  23. int Maximum(SuperTableau a)
  24. {
  25.    int m;
  26.    // ..... parcourir a
  27.    return m;
  28. }
  29. int main()
  30. {
  31.    SuperTableau a;     
  32.    a.Resize(50);
  33.    // .... remplir a
  34.    Maximum(a);
  35.    Maximum(a);
  36. }


 
Pourquoi ce code plante-t-il? C'est un exemple de code ou l'erreur n'est pas du tout au meme endroit que la ou ca plante... En gros ca va foirer pendant le deuxieme appel a Maximum, mais l'erreur n'est pas du tout la...puisque Maximum ne fait rien - ou presque.

Message cité 1 fois
Message édité par Ace17 le 21-12-2006 à 17:27:54
Reply

Marsh Posté le 22-12-2006 à 09:08:11    

Ace17 a écrit :

Exemple amusant :
[...]
Pourquoi ce code plante-t-il? C'est un exemple de code ou l'erreur n'est pas du tout au meme endroit que la ou ca plante... En gros ca va foirer pendant le deuxieme appel a Maximum, mais l'erreur n'est pas du tout la...puisque Maximum ne fait rien - ou presque.


C'est peut-être un exemple un peu subtil pour un débutant, non ?


---------------
TriScale innov
Reply

Marsh Posté le 22-12-2006 à 11:28:05    

franceso a écrit :

C'est peut-être un exemple un peu subtil pour un débutant, non ?


Tu as raison, je me suis emballé. C'était pour montrer que ce n'est pas forcément la ligne ou ca plante qu'il faut corriger.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed