1

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):

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

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?

Edit: 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?

Josh G.
  • 29
  • 5
  • What is `result`, the same as `s2`? The provided code snippet is not clear. – Yirkha Apr 24 '14 at 00:42
  • Also better use `SDL_malloc()` for the `abuf` copy instead, that's what it uses internally (and might not be the same as system `malloc()`). – Yirkha Apr 24 '14 at 00:49
  • @Yirkha Oops, I copied the code wrong when posting. result is supposed to be s2--I'll fix that. I will try SDL_malloc(), though all other open source projects I've seen use plain malloc() and create their samples in memory with no problems... – Josh G. Apr 24 '14 at 01:23
  • @Yirkha Turns out SDL_malloc() is simply "return malloc(size);", so no difference there. Still looking into memory issues since the crash has got to be related to the heap, though. – Josh G. Apr 24 '14 at 01:28

1 Answers1

1

It seems that the problem is with multiple heaps on Windows.

When I analyzed the sample code in the debugger, the SDL_mixer function Mix_FreeChunk() used free() from msvcrt.dll, while the calling code called malloc() from one of the modern Visual C Runtime Libraries (like msvcr110.dll or static version).

It doesn't make difference if you call SDL_malloc() for this, because it is indeed just #define SDL_malloc malloc.

The one solution I see is just to force use the malloc() from msvcrt.dll too:

#include <windows.h>

...

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

...

Mix_Chunk* s2 = (Mix_Chunk*)msvcrt_malloc(sizeof(Mix_Chunk));
s2->abuf = (Uint8*)msvcrt_malloc(s2->alen * sizeof(Uint8));

The program stopped crashing then for me.

Better option might be to just compile the SDL_mixer and/or SDL libraries yourself, with exactly the same environment settings as your final application.

Yirkha
  • 12,737
  • 5
  • 38
  • 53
  • Wow, thanks for checking this out for me. IT WORKS! You are correct in that I didn't compile the libraries myself, I'm using some that were pre-compiled years ago (mostly because I have trouble compiling libraries myself), and those were certainly done under a different environment. I'm using VS2010 for the current application. Ideally I should get everything compiled myself. Never would've figured this out without your help :D – Josh G. Apr 24 '14 at 02:01
  • I have no rep on stack overflow yet so I can't upvote you, but I'll definitely be back here to do it when I can! – Josh G. Apr 24 '14 at 02:05
  • Good, I have fortunately also downloaded some pre-built package, otherwise I might not be able to reproduce it so easily... Anyway, you're welcome, I'm glad you got it working! – Yirkha Apr 24 '14 at 02:15