简体   繁体   中英

realloc crashing in previously stable function

Apparently this function in SDL_Mixer keeps dying, and I'm not sure why. Does anyone have any ideas? According to visual studio, the crash is caused by Windows triggering a breakpoint somewhere in the realloc() line.

The code in question is from the SVN version of SDL_Mixer specifically, if that makes a difference.

static void add_music_decoder(const char *decoder) 
{ 
  void *ptr = realloc(music_decoders, num_decoders * sizeof (const char **)); 
  if (ptr == NULL) { 
    return; /* oh well, go on without it. */ 
  } 
  music_decoders = (const char **) ptr; 
  music_decoders[num_decoders++] = decoder; 
} 

I'm using Visual Studio 2008, and music_decoders and num_decoders are both correct (music_decoders contains one pointer, to the string "WAVE", and music_decoders. ptr is 0x00000000, and the best I can tell, the crash seems to be in the realloc() function. Does anyone have any idea how I could handle this crash problem? I don't mind having to do a bit of refactoring in order to make this work, if it comes down to that.

For one thing, it's not valid to allocate an array of num_decoders pointers, and then write to index num_decoders in that array. Presumably the first time this function was called, it allocated 0 bytes and wrote a pointer to the result. This could have corrupted the memory allocator's structures, resulting in a crash/breakpoint when realloc is called.

Btw, if you report the bug, note that add_chunk_decoder (in mixer.c) is broken in the same way.

I'd replace

void *ptr = realloc(music_decoders, num_decoders * sizeof (const char **));

with

void *ptr = realloc(music_decoders, (num_decoders + 1) * sizeof(*music_decoders)); 

Make sure that the SDL_Mixer.DLL file and your program build are using the same C Runtime settings. It's possible that the memory is allocated using one CRT, and realloc'ed using another CRT.

In the project settings, look for C/C++ -> Code Generation. The Runtime Library setting there should be the same for both.

music_decoders[num_decoders++] = decoder;

You are one off here. If num_decoders is the size of the array then the last index is num_decoders - 1. Therefore you should replace the line with:

music_decoders[num_decoders-1] = decoder;

And you may want to increment num_decoders at the beginning of the function, not at the end since you want to reallow for the new size, not for the old one.

One additional thing: you want to multiply the size with sizeof (const char *), not with double-star.

Ah, the joys of C programming. A crash in realloc (or malloc or free) can be triggered by writing past the bounds of a memory block -- and this can happen anywhere else in your program. The approach I've used in the past is some flavor of debugging malloc package. Before jumping in with a third party solution, check the docs to see if Visual Studio provides anything along these lines.

Crashes are not generally triggered by breakpoints. Are you crashing, breaking due to a breakpoint or crashing during the handling of the breakpoint?

The debug output window should have some information as to why a CRT breakpoint is being hit. For example, it might notice during the memory operations that guard bytes around the original block have been modified (due to a buffer overrun that occurred before add_music_decoder was even invoked). The CRT will check these guard pages when memory is freed and possibly when realloced too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM