Ich habe Probleme mit einem Spiel, an dem ich gearbeitet habe, wo ich, nachdem ich Musik hinzugefügt habe, Segfaulting in meinem häufig aufgerufenen Texture-loading Code zwischen 5-30 Sekunden nach dem Start gestartet habe . Das Beste, was mir einfiel, war, dass es sich um eine Art von Speicherkorruption handelt. Nach einer guten Woche, in der ich erfolglos versuchte, es zu debuggen (Dinge wie GFlags pageheap auszuprobieren), schaffte ich es, es auf den folgenden Code zu reduzieren, der immer noch das Problem aufweist.Mix_PlayMusic verursacht Speicherbeschädigung
Manchmal segfold dieses Segment mit dem Callstack, der SDL2_mixer.dll
durchläuft, aber meist tritt es in dem SDL_CreateTextureFromSurface
Aufruf auf, da der Renderer in einem fehlerhaften Zustand ist. numTextures wird auf meinem Rechner zwischen 15000-40000 (Windows 10 x64, mit Programm für x86 kompiliert).
Mein Bauchgefühl sagt mir, dass es ein Problem in meiner Umgebung oder Code, aber kein Problem in SDL selbst, aber ich bin ratlos. Jede Hilfe oder Einsichten würde sehr geschätzt werden.
#include <SDL_image.h>
#include <SDL_mixer.h>
#include <cassert>
int main(int argc, char* argv[])
{
assert(SDL_Init(SDL_INIT_EVERYTHING) == 0);
SDL_Window * pWindow_ = SDL_CreateWindow(
"", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0x0);
assert(pWindow_ != nullptr);
SDL_Renderer * pRenderer_ = SDL_CreateRenderer(pWindow_, -1, 0);
assert(pRenderer_ != nullptr);
assert(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 512) == 0);
Mix_Music * pMusic = Mix_LoadMUS("sounds/tranquility.wav");
assert(pMusic != nullptr);
assert(Mix_PlayMusic(pMusic, -1) == 0);
SDL_Surface * pSurface = IMG_Load("images/caution.png");
assert(pSurface != nullptr);
SDL_Texture * pTexture = SDL_CreateTextureFromSurface(pRenderer_, pSurface);
assert(pTexture != nullptr);
int numTextures = 0;
while (true)
{
numTextures += 10;
assert(pTexture != nullptr);
SDL_DestroyTexture(pTexture);
pTexture = SDL_CreateTextureFromSurface(pRenderer_, pSurface);
assert(pTexture != nullptr);
}
}
Haben Sie überprüft, dass 'Mix_LoadMUS()' ein nicht-NULL 'Mix_Music *' zurückgibt? Die ['Mix_PlayMusic()' docs] (https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC57) sagt nichts darüber aus, wie man NULL 'music' Argumente vernünftig behandeln kann. Dito für Ihren 'IMG_Load()' Anruf. – genpfault
@genpfault gutes Denken. Ich habe Null-Prüfungen für pTexture vor dem Zerstören und nach dem Erstellen und in Mix_LoadMUS hinzugefügt. Ich habe auch in Mix_PlayMusic für null behauptet. Keine dieser Behauptungen versagt. Und es ist erwähnenswert, dass bis zum Absturz die Musik wie erwartet abgespielt wird. –
Hervorragend, vielen Dank für die doppelte Überprüfung und Aktualisierung des MCVE! Als nächstes: hast du SDL2, SDL_mixer, & SDL_image mit deinem Compiler deiner Wahl gebaut (ich vermute ein Visual Studio der letzten Zeit?) Oder benutzt du die Binaries von libsdl.org? Wenn Sie die Binärdateien verwenden, versuchen Sie, sie lokal im Debug- oder RelWithDebInfo-Modus zu erstellen, damit Ihre Rückverfolgungsfunktionen verständlicher werden. Eine andere Sache, die Sie ausprobieren sollten, ist das Hinzufügen eines 'SDL_PumpEvents()' zu Ihrer 'while' Schleife. Sorry, ich habe nichts besseres, was Sie haben, sieht OK für mich aus :( – genpfault