Освобождение допустимой поверхности SDL приводит к segfault

[Решено] Забыл реализовать конструктор копирования и оператор присваивания. Экземпляр, которому назначено использование копирования по умолчанию, получит тот же указатель, что и экземпляр, создавший поверхность, на которую он указывает. Однажды один из них разрушает или звонит перерисовывать(), другой сохраняет указатель на свободную память, и это вызывает ошибку сегментации.


У меня есть класс для текстовых меток в моем приложении. Когда его свойства изменяются, он автоматически перерисовывается в свою личную поверхность.

Как правило, перерисовка выглядит так:

void Text::redraw() {
if(_font==0) return;
if(_image) {
SDL_FreeSurface(_image); //this line throwing a segfault
_image = 0;
}

_image = TTF_RenderUTF8_Blended(_font, _text.c_str(), _color);
}

Но код вылетает при освобождении поверхности (конечно, только допустимые, так как указатель равен 0, когда у него нет поверхности для освобождения).

Также странно, что на некоторых машинах код работает хорошо и освобождает память. Но на других он падает.

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


Я устанавливаю _образ до 0 в конструкторе. Нет кода, который меняет _образ значение или освобождает поверхность, за исключением перерисовывать() функция (и деструктор).

Каким-то образом освобождает сбой памяти только на XP. Если я закомментирую освобождающую часть, она не рухнет. Оба варианта хорошо работают на win7 (как x86, так и x64).

0

Решение

Если исходить из того, что мы, как правило, знаем, что SDL работает хорошо, у нас остаются следующие варианты (я не могу думать ни о каких других, но вполне могут быть некоторые)

  • Возможность того, что библиотека была построена неправильно
  • Включающий текст каким-то образом копируется где-то еще в коде (ломая правило 3
  • Что-то еще вызывает SDL_FreeSurface с тем же указателем
  • Что-то еще попирает кучу (возможно, но маловероятно, так как это единственный случай, который, как вы сказали, дает сбой);

Поэтому я обычно отлаживаю это, добавляя некоторые (grep’able) printfs следующим образом, а затем проверяю вывод построчно:

void Text::redraw() {
if(_font==0) return;
if(_image) {
fprintf(stderr,"## $%x freeing $%x",this, _image);
SDL_FreeSurface(_image);
_image = 0;
}

_image = TTF_RenderUTF8_Blended(_font, _text.c_str(), _color);
fprintf(stderr,"## $%x allocated $%x",this, _image);
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]