Der unique_ptr<> gibt mir nen Segfault...



  • Hi,

    Ich habe einen unique_ptr<> auf SDL.Mix_Music, weil ich jedes Mal die Sample Rate neu setzen will. Jedes Mal, wenn man bei meiner Klasse (music) die open()-Methode aufruft, wird die SDL neu initialisiert (mit dem Wert der Sample Rate) und auch der unique_ptr<Mix_Music, music_deleter> wird resettet, mit Mix_LoadMUS.

    Sobald ich aber zum zweiten Mal open() aufrufe, geht mir das Programm durch die Lappen und ich habe keine Ahnung, warum das so sein könnte.

    class music{
            struct music_deleter{
                void operator()(Mix_Music* music){
                    Mix_FreeMusic(music);
                }
            };
    
            std::unique_ptr<Mix_Music, music_deleter> music_handle;
            std::unique_ptr<detail::music_initializer> initializer;
    
        public:
    ...
            void open(const std::string& file_path){
                initializer.reset(new detail::music_initializer(file_path.c_str()));
                music_handle.reset(Mix_LoadMUS(file_path.c_str()));
    
                if(!music_handle)
                    throw std::runtime_error{Mix_GetError()};
            }
    ...
    };
    

    Wenn ich den Fehler debugge, zeigt er mir Zeile 4, in den Deleter von music_handle. Aber das kann doch nicht sein! Ich benutze ja schließlich einen unique_ptr<>, sogar mit speziellem Deleter. Wie man in Zeile 17 bis 18 erkennt, prüfe ich auch nach, ob das reset()en auch wirklich geklappt hat, und tatsächlich, es klappt jedes Mal, da keine Exception geworfen wird.

    Der Stacktrace sieht für mich auch nicht falsch aus. Es wird open() aufgerufen -> es wird unique_ptr<>::reset() aufgerufen -> es wird der Deleter aufgerufen -> es wird Mix_FreeMusic aufgerufen. Für mich sieht die Reihenfolge korrekt aus.

    Folgender Stacktraceauszug:

    1  MPEG::Stop()                                                                                                                                                                                       0x7fffbd96b67b 
    2  ??                                                                                                                                                                                                 0x7ffff788726d 
    3  Mix_FreeMusic                                                                                                                                                                                      0x7ffff788823b 
    4  sdl::music::music_deleter::operator()                                                                                                                                music.hpp                 53  0x40ccf9       
    5  std::unique_ptr<_Mix_Music, sdl::music::music_deleter>::reset                                                                                                        unique_ptr.h              344 0x41ae1c       
    6  sdl::music::open                                                                                                                                                     music.hpp                 69  0x4165e4       
    7  main_window::play                                                                                                                                                    main_window.cpp           188 0x413677       
    8  main_window::play                                                                                                                                                    main_window.cpp           203 0x41249a
    

    Es geht übrigens um mp3-Dateien (ja, die sind ein Muss für einen Music Player).

    Und ich bin jetzt mit meinen Debugging-Kräften am Ende und wollte hier mal nachfragen, ob da einer weiß, was ich falsch mach?



  • Kellerbewohner schrieb:

    Jedes Mal, wenn man bei meiner Klasse (music) die open()-Methode aufruft, wird die SDL neu initialisiert

    Wenn Du die "SDL neu initialisiert" hast, darfst Du dann noch mit den alten Zeigern hantieren?



  • Caligulaminus schrieb:

    Wenn Du die "SDL neu initialisiert" hast, darfst Du dann noch mit den alten Zeigern hantieren?

    Wow, danke!

    music_handle.reset();
                initializer.reset(new detail::music_initializer(file_path.c_str()));
                music_handle.reset(Mix_LoadMUS(file_path.c_str()));
    

Anmelden zum Antworten