Вопрос

Судя по всему, эта функция в SDL_Mixer продолжает умирать, и я не знаю почему.У кого-нибудь есть идеи?По данным Visual Studio, сбой вызван тем, что Windows запускает точку останова где-то в строке realloc().

Рассматриваемый код взят из версии SDL_Mixer для SVN, если это имеет значение.

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; 
} 

Я использую Visual Studio 2008, и music_decoders и num_decoders верны (music_decoders содержит один указатель на строку «WAVE», а music_decoders.ptr равен 0x00000000, и насколько я могу судить, сбой, похоже, произошел в функции realloc().Кто-нибудь знает, как я могу справиться с этой проблемой сбоя?Я не против провести небольшой рефакторинг, чтобы все заработало, если до этого дойдет.

Это было полезно?

Решение

Во-первых, неправильно выделять массив num_decoders указатели, а затем записать в index num_decoders в этом массиве.Предположительно при первом вызове этой функции она выделила 0 байт и записала указатель на результат.Это могло привести к повреждению структур распределителя памяти, что привело бы к сбою/точке останова при realloc называется.

Кстати, если вы сообщите об ошибке, обратите внимание, что add_chunk_decoder (в mix.c) ломается таким же образом.

я бы заменил

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

с

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

Другие советы

Убедитесь, что файл SDL_Mixer.DLL и сборка вашей программы используют одни и те же настройки среды выполнения C.Возможно, что память выделяется с использованием одного CRT и перераспределяется с помощью другого CRT.

В настройках проекта найдите C/C++ -> Генерация кода.Настройки библиотеки времени выполнения должны быть одинаковыми для обоих.

music_decoders[num_decoders++] = декодер;

Ты здесь один из таких.Если num_decoders — это размер массива, то последний индекс — num_decoders — 1.Поэтому вам следует заменить строку на:

music_decoders[num_decoders-1] = декодер;

И вы можете увеличить num_decoders в начале функции, а не в конце, поскольку вы хотите повторно разрешить новый размер, а не старый.

Еще одна вещь:вы хотите умножить размер на sizeof (const char *), а не на двойную звезду.

Ах, радости программирования на C.Сбой в realloc (или malloc или free) может быть вызван записью за пределы блока памяти - и это может произойти где угодно в вашей программе.Подход, который я использовал в прошлом, представляет собой разновидность отладка malloc упаковка.Прежде чем переходить к стороннему решению, проверьте документацию, чтобы узнать, предоставляет ли Visual Studio что-либо подобное.

Сбои обычно не вызываются точками останова.У вас происходит сбой, сбой из-за точки останова или сбой во время обработки точки останова?

Окно вывода отладки должно содержать некоторую информацию о том, почему сработала точка останова CRT.Например, во время операций с памятью он может заметить, что защитные байты вокруг исходного блока были изменены (из-за переполнения буфера, произошедшего еще до того, как был вызван add_music_decoder).CRT будет проверять эти защитные страницы при освобождении памяти и, возможно, при ее перераспределении.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top