Se connecter avec
S'enregistrer | Connectez-vous

[C++] Problème de segmentation - std::stack

Dernière réponse : dans Programmation

Bonjour à tous !

J'expérimente une nouvelle façon de gérer mes événements en SDL. Je voulais utiliser la pile (ou <i>stack</i>), mais j'ai des petits problèmes de violation d'accès (ou de segmentation).

Voici mon code :

  1. #include <stack>
  2.  
  3. struct StateStruct
  4. {
  5. void (*StatePointer)();
  6. };
  7.  
  8. stack<StateStruct> StateStack;
  9.  
  10. ...
  11.  
  12. StateStruct state;
  13. state.StatePointer = Exit;
  14. StateStack.push(state);
  15.  
  16. state.StatePointer = Menu;
  17. StateStack.push(state);
  18.  
  19. ...


Voilà. Le problème vient de là : si je met cette partie en commentaire, ça marche (mise à part quelques petits problèmes après dans le programme).

Merci beaucoup à tous mes sauveurs ! :) 

Autres pages sur : probleme segmentation std stack

Lassé par la pub ? Créez un compte
Expert Programmation

Je crois me souvenir qu'en C++ les "struct" sont en fait des "class".
quand tu fais la pile, le constructeur par recopie est appelé pour copier l'objet, peut-être qu'il y a un problème de ce côté.

Tu devrais essayer de gérer des pointeurs pour éviter de faire des copies:
  1. #include <stack>
  2.  
  3. struct StateStruct
  4. {
  5. void (*StatePointer)();
  6. };
  7.  
  8. stack<StateStruct *> StateStack;
  9.  
  10. ...
  11.  
  12. StateStruct state1;
  13. state1.StatePointer = Exit;
  14. StateStack.push(&state1);
  15.  
  16. StateStruct state2;
  17. state2.StatePointer = Menu;
  18. StateStack.push(&state2);
  19.  
  20. ...

mais attention à zone de définition des variables
Expert Programmation

Il faut voir que c'est un pointeur que tu passes, il faut donc gérer toi-même la mémoire de tous les objets (création par des new et destruction par des delete) si tu comptes faire sortir un objet de ta fonction.

Comment cela ?

Quelques détails supplémentaires : en fait je me sers des quelques lignes précédentes pour indiquer quel est l'état. J'ai pour ce faire trois fonctions : Exit(), Game() et Menu() qui gèrent toutes trois des parties différentes du jeu.

Je me sers du pointeur StatePointer pour simplement renvoyer la fonction à utiliser par l'intermédiaire de :

  1. int main(int argc, char** argv)
  2. {
  3. Init();
  4.  
  5. while(!StateStack.empty())
  6. {
  7. StateStack.top()->StatePointer();
  8. }
  9.  
  10. Shutdown();
  11. return 0;
  12. }


Voilà l'ossature de mon programme ! Mais je ne pense pas qu'il faille créer quoi que ce soit, vu que la variable StateStack est créee en globale...
Expert Programmation

Statestack est effectivement créé en globla, mais il faut aussi que les objets mis dedans le soient, car si tu crée state1 en local sans utiliser new dans ta fonction Init(), il sera détruit à la sortie de la fonction, et au final, tu auras dans ta pile un pointeur qui pointera dans une zone mémoire non aloué et où il n'y a rien => résultat crash de l'application quand tu va appeler un élément de la pile.

Donc il te faut faire des new pour tout objets mis dans la pile. Et du coup faire des delete avant la suppression de la pile (car sinon tu supprime la pile sans supprimer les objets contenus).

Effectivement ! Ca marche beaucoup mieux maintenant ! Au moins, ça a des points positifs : j'ai jamais autant vu de cours sur les pointeurs et sur les std::stack en si peu de temps !

Eh bien, merci beaucoup ! Je peux enfin tenter de terminer mon programme, avant le prochain problème ! ;) 
Lassé par la pub ? Créez un compte
Tom's guide dans le monde