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

Auteur Sujet: segfault avec sf::Music  (Lu 3556 fois)

0 Membres et 1 Invité sur ce sujet

stvince

  • Newbie
  • *
  • Messages: 7
    • Voir le profil
    • E-mail
segfault avec sf::Music
« le: Janvier 14, 2015, 01:07:21 pm »
Bonjour, alors je ne sais pas pourquoi, j'ai mon play et mon getDuration qui segfault PARFOIS.

j'utilise les même méthodes statiques dans mon programme, mais le problème se retrouve dans une boucle simple:

Sound.cpp:
#include "Sound.hpp"
#include "Assets.hpp"

static int                                              _m;
static std::vector<sf::Music*>          _music;

bool    Sound::load()
{
  for (int i = 0; i < 4; i++)
    {
      std::stringstream ss;
      ss << "res/sound/music/" << i + 1 << ".wav";
      sf::Music *music = new sf::Music();
      if (!music->openFromFile(ss.str()))
        {
          std::cout << "cannot load " << ss.str() << std::endl;
          return (false);
        }
      music->setVolume(50);
      music->setLoop(true);
      _music.push_back(music);
      //Assets::add_load();
    }
  _m = 0;
  _music[_m]->play();
  return (true);
}

bool    Sound::swap(const int &next)
{
  if (Config::get_bool("sound") && _music[next] != NULL && _m != next)
  {
    if (_music[next]->getDuration() >= _music[_m]->getPlayingOffset())
      _music[next]->setPlayingOffset(_music[_m]->getPlayingOffset());
    _music[_m]->stop();
    _music[next]->play();
    _m = next;
    return (true);
  }
  return (false);
}

le Sound.hpp:
#ifndef SOUND_H_
# define SOUND_H_

# include <SFML/Audio.hpp>
# include <iostream>
# include <sstream>
# include <string>
# include <dirent.h>
# include <vector>
# include "Config.hpp"

class Sound
{
public:
  static bool   swap(const int &m);
  static bool   load();
};

#endif /*!SOUND_H_*/


donc voilà, j'appelle évidemment Sound::load() au début du programme, et lorsque je fais appel à Sound::swap(), j'ai environ une foi sur 10 un segfault.

gdb me sort:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7573360 in sf::Music::getDuration() const () from lib/64/libsfml-audio.so.2

ou bien la même avec Play() ou Stop().

c'est probablement une erreur toute conne mais je n'arrive pas à mettre le doigt dessus.

merci beaucoup d'avoir pris le temps de lire ce bout de code et merci d'avance pour vos (éventuelles) réponses.
bonne journée

Cpl.Bator

  • Hero Member
  • *****
  • Messages: 540
    • Voir le profil
Re : segfault avec sf::Music
« Réponse #1 le: Janvier 15, 2015, 01:41:38 pm »
bool    Sound::load()
{
  for (int i = 0; i < 4; i++)
    {
      std::stringstream ss;
      ss << "res/sound/music/" << i + 1 << ".wav";
      sf::Music *music = new sf::Music();
      if (!music->openFromFile(ss.str()))
    {
      std::cout << "cannot load " << ss.str() << std::endl;
      return (false);
    }
      music->setVolume(50);
      music->setLoop(true);
      _music.push_back(music);
      //Assets::add_load();
    }
  _m = 0;
  _music[_m]->play();
  return (true);
}

Je crois que ta musique est détruite à la fin de ta méthode de chargement, donc parfois , sa plante.
tu stockes des pointeurs qui sont détruit a la fin de ta méthode , essaye sans les pointeurs.

stvince

  • Newbie
  • *
  • Messages: 7
    • Voir le profil
    • E-mail
Re : segfault avec sf::Music
« Réponse #2 le: Janvier 15, 2015, 02:06:14 pm »
Déjà merci de ta réponse
En revanche sf::Music est non copiable, ce qui signifie que je ne peux pas la pushback dans mon vector, donc impossible sans pointeur (de cette manière en tout cas).

et... je me trompe peut-être mais le pointeur ne se détruit pas à la fin de la méthode car:
static std::vector<sf::Music*>      _music;
n'est pas propre à la méthode.

Si c'est le cas, comment vérifier autrement que par le:
&& _music[next] != NULL
?
normalement, si le pointeur était effectivement détruit, ça ne passerait pas le if

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : segfault avec sf::Music
« Réponse #3 le: Janvier 15, 2015, 02:13:25 pm »
Le pointeur est bien détruit, mais pas l'instance pointée. Donc tes sf::Music restent bien en vie après la méthode de chargement.

Quant au test "!= NULL", il ne sert à rien puisque tu ne mets jamais NULL dans les cases de ton tableau, uniquement des pointeurs valides.

Si tu veux un peu plus d'aide, il faudrait montrer un code complet et minimal qui reproduit le problème, et pas un extrait incomplet de ton code original.
Laurent Gomila - SFML developer

stvince

  • Newbie
  • *
  • Messages: 7
    • Voir le profil
    • E-mail
Re : segfault avec sf::Music
« Réponse #4 le: Janvier 15, 2015, 03:05:52 pm »
voici un code complet utilisant la boucle du tuto. j'en profite pour préciser que toutes les musiques ont la même durée (au cas ou :p)
Sound.cpp
#include "Sound.hpp"

static int                              _m;
static std::vector<sf::Music*>      _music;

bool    Sound::load()
{
  for (int i = 0; i < 4; i++)
    {
      std::stringstream ss;
      ss << "res/" << i + 1 << ".wav";
      sf::Music *music = new sf::Music();
      if (!music->openFromFile(ss.str()))
        {
          std::cout << "cannot load " << ss.str() << std::endl;
          return (false);
        }
      music->setVolume(50);
      music->setLoop(true);
      _music.push_back(music);
    }
  _m = 0;
  _music[_m]->play();
  return (true);
}

bool    Sound::swap(const int &next)
{
  if (_m != next)
    {
      if (_music[next]->getDuration() >= _music[_m]->getPlayingOffset())
        _music[next]->setPlayingOffset(_music[_m]->getPlayingOffset());
      _music[_m]->stop();
      _music[next]->play();
      _m = next;
      return (true);
    }
  else
    {
      std::cout << "même musique: pas de changement" << std::endl;
      return (false);
    }
}
 

Sound.hpp:
#ifndef SOUND_H_
# define SOUND_H_

# include <SFML/Audio.hpp>
# include <iostream>
# include <sstream>
# include <vector>

class Sound
{
public:
  static bool   swap(const int &m);
  static bool   load();
};

#endif /*!SOUND_H_*/

Main.cpp
#include <SFML/Window.hpp>
#include "Sound.hpp"
int main()
{
  sf::Window window(sf::VideoMode(800, 600), "My window");
  sf::Clock clock;

  if (Sound::load())
    while (window.isOpen())
      {
        sf::Event event;
        while (window.pollEvent(event))
          {
            if (event.type == sf::Event::Closed)
              window.close();
          }
        if (clock.getElapsedTime().asSeconds() >= 1)
          {
            clock.restart();
            if (Sound::swap(std::rand() % 4))
              std::cout << "ok" << std::endl;
            else
              std::cout << "pas ok" << std::endl;
          }
        window.display();
      }
  return (0);
}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : segfault avec sf::Music
« Réponse #5 le: Janvier 15, 2015, 03:11:25 pm »
Que dit ton debugger (et notamment la pile d'appels) après le crash ?

Essaye aussi d'enlever ou de bouger les différents appels à getDuration / getPlayingOffset / setPlayingOffset pour voir quelle configuration exacte provoque le crash. Commence par le plus simple : vire tout (garde juste stop() et play()).
Laurent Gomila - SFML developer

Cpl.Bator

  • Hero Member
  • *****
  • Messages: 540
    • Voir le profil
Re : segfault avec sf::Music
« Réponse #6 le: Janvier 15, 2015, 04:22:19 pm »
Autant pour moi, je suis aller un peu vite en besogne , j'ai testé ton code, il ne crash pas. le problème viens surement d'ailleurs.

stvince

  • Newbie
  • *
  • Messages: 7
    • Voir le profil
    • E-mail
Re : segfault avec sf::Music
« Réponse #7 le: Janvier 15, 2015, 09:52:34 pm »
Justement Cpl.Bator, j'allais poster pour dire que je suis désolé de vous avoir dérangé, il s'agissait seulement d'un fichier wav foireux
je m'en veux de vous avoir embêté pour ça, et d'avoir perdu autant de temps pour un truc aussi con.

en tout cas, merci à vous deux pour votre aide