The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
SDL_Mixer: Mix_FreeChunk() crashing on sample created in mem
gejiaxu


Joined: 23 Apr 2014
Posts: 5
I was working on adding randomized pitch to sound samples, and that works fine now, but Mix_FreeChunk() crashes when trying to free the chunk after I'm done using it.

I made a simplified test to recreate the issue (SDL 1.2.14 and SDL_mixer 1.2.11):
Code:
Mix_Chunk* s1 = rexResourceMgr->getSoundFromFile("data/audio/UI/ALARM.ogg"); // uses Mix_LoadWAV_RW/SDL_RWops to load sample

Mix_Chunk* s2 = (Mix_Chunk*)malloc(sizeof(Mix_Chunk));
result->allocated = 1;
result->alen = s1->alen;
result->abuf = (Uint8*)malloc(result->alen * sizeof(Uint8));
memcpy(result->abuf,s1->abuf,result->alen);
result->volume = s1->volume;

Mix_FreeChunk(s1); // <-- works fine
Mix_FreeChunk(s2); // <-- crashes somewhere in SDL/SDL_Mixer
s1 is loaded from a file using Mix_LoadWAV_RW, and s2 is an exact copy of s1 created in memory. The latter crashes when freed, but the former doesn't. Anyone have any clues as to why this might be happening? I've spent hours on this and narrowed it down to something happening in SDL_Mixer, but I don't have a way to see what's going on in the underlying source when it crashes, and now the test is so simple it's an *exact copy* of the original sample, but still fails...

An example of the specific error message: "First-chance exception at 0x77c5e3be in game.exe: 0xC0000005: Access violation reading location 0x69b0f1d8."

Why isn't it able to free the memory?
gejiaxu


Joined: 23 Apr 2014
Posts: 5
Just realized I copied the code wrong when posting the simplified test. "result" was supposed to be "s2". Fixed the code here:
Code:
Mix_Chunk* s1 = rexResourceMgr->getSoundFromFile("data/audio/UI/ALARM.ogg"); // uses Mix_LoadWAV_RW/SDL_RWops to load sample

Mix_Chunk* s2 = (Mix_Chunk*)malloc(sizeof(Mix_Chunk));
s2->allocated = 1;
s2->alen = s1->alen;
s2->abuf = (Uint8*)malloc(s2->alen * sizeof(Uint8));
memcpy(s2->abuf,s1->abuf,s2->alen);
s2->volume = s1->volume;

Mix_FreeChunk(s1); // <-- works fine
Mix_FreeChunk(s2); // <-- crashes somewhere in SDL/SDL_Mixer
gejiaxu


Joined: 23 Apr 2014
Posts: 5
After examining the isolated test some more, the freeing of s2 is specifically crashing in free.c during the HeapFree(_crtheap, 0, pBlock) call, so somehow the heap is corrupted in the space of those few lines? The intermediate code in Mix_FreeChunk() is actually quite simple, more or less just calling free() on the buffer. That being the case why would s1 be okay but s2 fail?
gejiaxu


Joined: 23 Apr 2014
Posts: 5
Sorry for spamming this but I can't edit posts and a solution has been found.

Turns out I was using pre-compiled SDL libs and if you do this and combine it with your own code, then the system may be using *different* versions of malloc()/free() at runtime. This naturally causes heap corruption, so the solution is to either make sure to compile SDL and your program in the same environment, or force the compiler to use the appropriate version of malloc.

Changing the above code to the following works fine:
Code:
Mix_Chunk* s1 = rexResourceMgr->getSoundFromFile("data/audio/UI/ALARM.ogg"); // uses Mix_LoadWAV_RW/SDL_RWops

Mix_Chunk* s2 = (Mix_Chunk*)msvcrt_malloc(sizeof(Mix_Chunk));
s2->allocated = 1;
s2->alen = s1->alen;
s2->abuf = (Uint8*)msvcrt_malloc(s2->alen * sizeof(Uint8));
memcpy(s2->abuf,s1->abuf,s2->alen);
s2->volume = s1->volume;

Mix_FreeChunk(s1); // <-- works fine
Mix_FreeChunk(s2); // <-- works fine now

where
Code:
typedef void* (*malloc_t)(size_t);
malloc_t msvcrt_malloc = reinterpret_cast<malloc_t>(
    GetProcAddress(GetModuleHandle(TEXT("msvcrt")), "malloc"));
SDL_Mixer: Mix_FreeChunk() crashing on sample created in mem
Juan Manuel Borges Caño
Guest

I like, and planned to use the pitch idea :-), does Mixer not have API for that?
gejiaxu


Joined: 23 Apr 2014
Posts: 5
No it doesn't, but you can manipulate the sample yourself in memory to achieve that effect. It can't be done in real-time, but you can at least make a copy of the sample and scale its pitch.
SDL_Mixer: Mix_FreeChunk() crashing on sample created in mem
Daniel Gibson
Guest

I think this is not only about "different versions of malloc/free" -
another problem is that on windows each DLL has its own heap.
Anyway, I guess the "proper" solution is to use SDL_malloc() and
SDL_free() for data you wanna allocate that SDL should free or for data
SDL allocated that you wanna free, so the corresponding data is handled
by SDLs heap and the malloc/free implementations SDL.dll was linked against.

Cheers,
Daniel

Am 24.04.2014 04:13, schrieb gejiaxu:
Quote:
Sorry for spamming this but I can't edit posts and a solution has been
found.

Turns out I was using pre-compiled SDL libs and if you do this and
combine it with your own code, then the system may be using *different*
versions of malloc()/free() at runtime. This naturally causes heap
corruption, so the solution is to either make sure to compile SDL and
your program in the same environment, or force the compiler to use the
appropriate version of malloc.

Changing the above code to the following works fine:







Code:
Mix_Chunk* s1 =
rexResourceMgr->getSoundFromFile("data/audio/UI/ALARM.ogg"); // uses
Mix_LoadWAV_RW/SDL_RWops

Mix_Chunk* s2 = (Mix_Chunk*)msvcrt_malloc(sizeof(Mix_Chunk));
s2->allocated = 1;
s2->alen = s1->alen;
s2->abuf = (Uint8*)msvcrt_malloc(s2->alen * sizeof(Uint8));
memcpy(s2->abuf,s1->abuf,s2->alen);
s2->volume = s1->volume;

Mix_FreeChunk(s1); // <-- works fine
Mix_FreeChunk(s2); // <-- works fine now


where







Code:
typedef void* (*malloc_t)(size_t);
malloc_t msvcrt_malloc = reinterpret_cast(
GetProcAddress(GetModuleHandle(TEXT("msvcrt")), "malloc"));



_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org