Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: sf::Clock et nullptr  (Lu 4636 fois)

0 Membres et 2 Invités sur ce sujet

lepiaff

  • Newbie
  • *
  • Messages: 12
    • Voir le profil
    • E-mail
sf::Clock et nullptr
« le: Août 09, 2014, 02:47:23 pm »
Salut,

Je ne pense pas que mon problème vienne de la classe sf::Clock mais plutôt de ma façon de programmer... Mais sait-on jamais.

J'ai donc une classe qui contient un attribut m_horloge de type sf::Clock. Cet attribut est initialisé à nullptr dans le constructeur.

J'ai ensuite une méthode comme celle-ci :
int cHorloge::time()
{
        if(m_horloge == nullptr)
                return 0;

        return int(m_horloge->getElapsedTime().asMilliseconds());
}
 

J'ai un segfault sur la ligne du if... On ne peut pas faire comme ça ? j'ai aussi essayé avec NULL et avec 0. Je ne comprend pas.

Merci de bien vouloir m'expliquer :).

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::Clock et nullptr
« Réponse #1 le: Août 09, 2014, 03:04:43 pm »
Comment est initialisé m_horloge ? Et sinon quelle raison obscure te pousse à passer par un pointeur + allocation dynamique pour ça ?
Laurent Gomila - SFML developer

lepiaff

  • Newbie
  • *
  • Messages: 12
    • Voir le profil
    • E-mail
Re : sf::Clock et nullptr
« Réponse #2 le: Août 09, 2014, 03:40:56 pm »
Dans le constructeur je fais simplement :
m_horloge = nullptr;

La raison obscure est simple (dans mon esprit). Nul doute que je ne fais pas comme il le faudrait, cependant j'essaye de trouver des solution par moi même avant de chercher mieux ailleurs (alors on ne se moque pas !) :p.

Mon programme va en boucle chercher la valeur de horloge pour mettre à jour la frame d'une animation. Si le temps est supérieur à 100 ms alors je passe à la frame suivante.
Sauf que je souhaite pouvoir mettre l'animation en pause et donc j'utilise une méthode animation.pause().
Comme je n'ai pas trouvé le moyen avec sf::Clock de stopper le compteur, je le supprime et si sf::Clock n'existe pas, je renvoi 0. Comme le compteur est à 0, mon animation garde toujours la même frame. Je suis peut être pas très clair, je m'en excuse.

je changerais très certainement cette façon de faire mais le problème reste entier... Je ne comprend pas l'erreur que j'obtiens.

merci  :D

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::Clock et nullptr
« Réponse #3 le: Août 09, 2014, 04:47:10 pm »
Citer
Dans le constructeur je fais simplement :
m_horloge = nullptr;
Et à quel moment est-ce que tu assignes autre chose qu'un pointeur nul à cette variable ?

Citer
Comme je n'ai pas trouvé le moyen avec sf::Clock de stopper le compteur, je le supprime et si sf::Clock n'existe pas, je renvoi 0. Comme le compteur est à 0, mon animation garde toujours la même frame. Je suis peut être pas très clair, je m'en excuse.
C'est un peu bourrin pour faire ça. Mais bon y a une logique derrière ce choix, et comme tu le dis il vaut mieux expérimenter par soi-même ;)

Personnellement j'ajouterais un booléen m_isPaused et je garderai un sf::Clock simple, sans pointeur ni allocation dynamique.
Laurent Gomila - SFML developer

lepiaff

  • Newbie
  • *
  • Messages: 12
    • Voir le profil
    • E-mail
Re : sf::Clock et nullptr
« Réponse #4 le: Août 09, 2014, 05:04:51 pm »
Citer
Et à quel moment est-ce que tu assignes autre chose qu'un pointeur nul à cette variable ?
Tout simplement dans la méthode void cHorloge::start() elle même appelée par cAnimation.play(). Si j'ai bien compris, le seul fait de créer le sf::Clock lance l'horloge, donc ça fait juste ce qu'il me faut.

Citer
Personnellement j'ajouterais un booléen m_isPaused et je garderai un sf::Clock simple, sans pointeur ni allocation dynamique.

Oui, j'y ai pensé, mais je me suis dit que laisser tourner le sf::Clock alors qu'on ne l'utilise pas, et ça, sur chaque entité qui possède une animation n'est pas une bonne idée. Tu l'auras compris, mon exemple fait référence à un jeu. Des personnages qui ne bougent pas en permanence, qui n'attaquent pas en permanence, un coffre qui peut être ouvert, etc. Vu qu'il pourrait y avoir un grand nombre d'entités de ce style en mémoire, j'ai pensé qu'il serait plus intéressant d’effacer l'horloge pour la recréer lorsque l'on en a besoin.

Peux-tu m'expliquer pourquoi ce n'est pas réellement une bonne chose ?

Merci :).
« Modifié: Août 09, 2014, 06:34:52 pm par lepiaff »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::Clock et nullptr
« Réponse #5 le: Août 09, 2014, 07:09:55 pm »
Citer
Peux-tu m'expliquer pourquoi ce n'est pas réellement une bonne chose ?
La gestion de la mémoire manuelle (new/delete) doit de manière général être évitée car c'est une source d'erreur potentielle. Il y a toujours une meilleure alternative, en l'occurence ici ne pas l'utiliser du tout :)

Citer
Oui, j'y ai pensé, mais je me suis dit que laisser tourner le sf::Clock alors qu'on ne l'utilise pas, et ça, sur chaque entité qui possède une animation n'est pas une bonne idée.
sf::Clock ne "tourne" pas comme le ferait une vraie horloge physique. Quand tu fais start() elle récupère le temps absolu courant, et quand tu fais getElapsedTime() elle fait pareil et effectue la différence entre les deux temps. Entre les deux appels, il ne se passe strictement rien ;)
Laurent Gomila - SFML developer

lepiaff

  • Newbie
  • *
  • Messages: 12
    • Voir le profil
    • E-mail
Re : sf::Clock et nullptr
« Réponse #6 le: Août 09, 2014, 07:57:20 pm »
Citer
La gestion de la mémoire manuelle (new/delete) doit de manière général être évitée car c'est une source d'erreur potentielle. Il y a toujours une meilleure alternative, en l'occurence ici ne pas l'utiliser du tout :)
Même dans ce genre de cas ou le risque d'erreur est très limité ? En effet, ici l'objet alloué dynamiquement n'est pas pointé par un autre objet. Je n'ai qu'un pointeur, je le créé avec start(), je le delete avec stop() et si il existe, je le détruit dans le destructeur.

Citer
sf::Clock ne "tourne" pas comme le ferait une vraie horloge physique. Quand tu fais start() elle récupère le temps absolu courant, et quand tu fais getElapsedTime() elle fait pareil et effectue la différence entre les deux temps. Entre les deux appels, il ne se passe strictement rien ;)
Bon bin vendu alors ! :). Merci pour l'explication, je vais de ce pas modifier ça.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::Clock et nullptr
« Réponse #7 le: Août 09, 2014, 08:59:23 pm »
Citer
Même dans ce genre de cas ou le risque d'erreur est très limité ? En effet, ici l'objet alloué dynamiquement n'est pas pointé par un autre objet. Je n'ai qu'un pointeur, je le créé avec start(), je le delete avec stop() et si il existe, je le détruit dans le destructeur.
Et le constructeur par copie ? L'opérateur d'affectation ? Le fait est que même si tu as besoin d'allocation dynamique, il n'y a pas de raison de ne pas au moins encapsuler ton pointeur dans un pointeur intelligent (unique_ptr, shared_ptr, ...).
Laurent Gomila - SFML developer

lepiaff

  • Newbie
  • *
  • Messages: 12
    • Voir le profil
    • E-mail
Re : sf::Clock et nullptr
« Réponse #8 le: Août 09, 2014, 09:11:59 pm »
Citer
Et le constructeur par copie ? L'opérateur d'affectation ? Le fait est que même si tu as besoin d'allocation dynamique, il n'y a pas de raison de ne pas au moins encapsuler ton pointeur dans un pointeur intelligent (unique_ptr, shared_ptr, ...).
Etant donné que mes connaissances en la matière sont encore limités, je vais écouter tes conseilles. J'ai lu quelque part que le pointeur intelligent de boost corrige une faille du pointeur intelligent de la bibliothèque standard. Que me conseilles-tu sachant que je n'ai pas encore boost et que c'est une grosse bibliothèque pour de si petits projets ?

Bon le problème initial existe toujours... je poste mon code :

Ma classe Horloge :
(click to show/hide)

Ma classe Animation :
(click to show/hide)

Le programme compile, se lance puis Segfault à la ligne
if(m_isPaused)

Ce ne serait pas que le type int n'est pas adapté à la taille d'un getElapsedTime().asMilliseconds() ?
Je sent que la solution va seulement démontrer que je suis un boulet ^^'.
« Modifié: Août 09, 2014, 10:18:19 pm par lepiaff »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::Clock et nullptr
« Réponse #9 le: Août 09, 2014, 10:43:44 pm »
Tu n'as pas besoin de boost, avec un compilo récent, qui supporte le C++11, tu as std::unique_ptr et std::shared_ptr qui couvrent la plupart des besoins.

Quant à ton plantage, il doit y avoir un problème en amont, dans le code qui utilise les classes que tu montres. Il est temps d'apprendre à se servir de ton debogueur ;)
Laurent Gomila - SFML developer

lepiaff

  • Newbie
  • *
  • Messages: 12
    • Voir le profil
    • E-mail
Re : sf::Clock et nullptr
« Réponse #10 le: Août 09, 2014, 11:37:53 pm »
Oki merci pour l'information, je vais essayer le pointeur intelligent :).

Pour le debogueur, j'essaye depuis tout à l'heure, mais a part me dire segfault quand j'arrive à la ligne en question...
Je vais refaire une passe sur le code alors.
Merci

lepiaff

  • Newbie
  • *
  • Messages: 12
    • Voir le profil
    • E-mail
Re : sf::Clock et nullptr
« Réponse #11 le: Août 10, 2014, 12:20:55 am »
m_isPaused au moment de l'erreur : Cannot access memory at address 0x28.
Je ne comprend pas.

Bon, bin sujet clos, ça n'a pas de rapport avec SFML ^^'.

Merci encore, à bientot  :).