сбой realloc в ранее стабильной функции - PullRequest
0 голосов
/ 07 июня 2009

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

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

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 (). Кто-нибудь имеет какие-либо идеи, как я мог бы решить эту проблему сбоя? Я не возражаю против необходимости немного рефакторинга, чтобы сделать эту работу, если это сводится к этому.

Ответы [ 5 ]

5 голосов
/ 07 июня 2009

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

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

Я бы заменил

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

с

void *ptr = realloc(music_decoders, (num_decoders + 1) * sizeof(*music_decoders)); 
2 голосов
/ 07 июня 2009

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

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

1 голос
/ 07 июня 2009

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

Вы здесь один. Если num_decoders - размер массива, то последним индексом является num_decoders - 1. Поэтому вам следует заменить строку на:

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

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

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

0 голосов
/ 07 июня 2009

Сбои обычно не инициируются точками останова. Вы терпите крах, ломаетесь из-за точки останова или сбиваетесь во время обработки точки останова?

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

0 голосов
/ 07 июня 2009

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

...