2016-01-09 2 views
-2

Я делаю приложение с использованием SDL 2. Недавно я начал использовать библиотеку SDL_Mixer, и это вызвало проблему для меня. Простите меня, если мое объяснение кажется расплывчатым, так как эта ошибка очень запутанна.Моя программа вылетает иногда, когда delete вызывается на один конкретный указатель

Иногда, когда вы закрываете мою программу, программа вылетает из строя. Только иногда это происходит. После удаления частей кода я обнаружил, что строка, вызывающая это, была простым вызовом delete на указателе типа Window*. Если я удалю этот вызов удаления, больше никаких сбоев не произойдет, когда я закрою программу. Еще одна важная вещь - отметить, что авария происходит сразу после того, как вызывается delete, что означает, что программа даже не входит в ~Window(), что действительно странно.

Что-то еще я заметил, что когда я удаляю вызов Mix_OpenAudio(...) с начала программы, никаких сбоев вообще не происходит, независимо от того, существует ли вызов удаления. Таким образом, инициализация SDL_Mixer имеет какое-то отношение к сбоям, но это просто добавляет больше путаницы.

Я надеюсь, что у кого-то есть представление о том, что может быть проблемой здесь, но если мое объяснение слишком расплывчато, я попытаюсь воспроизвести проблему в достаточно маленький сегмент кода, который я могу разместить здесь. Я не хотел копировать всю свою кодовую базу на этот вопрос, потому что я не хочу, чтобы мода ненавидела меня. Есть идеи?

ответ

0

Не видя кода в вопросе, вот мое предположение на двух наиболее вероятных причин:

  1. Ваше окно * указатель неинициализированным или указывает на незаконный адрес памяти.
  2. Окно, указанное через этот указатель, уже удалено, и вы снова пытаетесь удалить его. Это приводит к сбою, прежде чем вы попадете в деструктор, потому что то, что указывает Окно, уже не является допустимой памятью и не имеет vtable с указателем на деструктор.
0

Это, в основном, пример undefined behavior, который является особым условием, при котором не имеет никаких конкретных гарантий относительно того, что произойдет.

Удаление недействительного указателя - это действительно неопределенное поведение. Теперь проблема заключается в том, что вы должны понять, почему и когда указатель Window становится недействительным, некоторые намеки:

  • указателя является неинициализированным
  • указатель уже удален
  • указателя является результатом другой операции, которая приносит неопределенное поведение (например, разыменование члена недопустимого указателя)
  • Указатель хранился внутри переменной local/stack, которая больше недействительна при вызове delete (так что вы на самом деле не пытаетесь вообще удалить правильный указатель, например возвращает ссылку на указатель, хранящийся в локальном переменном способный по методу)
0

Я должен был протестировать, прежде чем ответить на ваш вопрос, но похоже, что моя память была правильной: если вы вызываете delete более одного раза на указатель, ваша программа выйдет из строя. Поэтому я думаю, что указатель, который вы удаляете, уже удален.

Вот мой тест: Running a simple test with g++

Я попытался установить р обнулить после его удаления, и что сделал следующее, если удастся. Но если я прокомментировал часть, которая устанавливает p в значение null, то если p обрабатывается как true, а программа разбилась.

enter image description here

Вам нужен способ, чтобы проверить и посмотреть, если указатель является недействительным или не перед удалением. К сожалению, я не знаю, как проверить указатель, чтобы увидеть, указывает ли он на действительные данные. Я думал, что простой «if (pointer)» будет работать, но, как вы можете видеть из моего последнего изображения, это не так.