[Решено] Забыл реализовать конструктор копирования и оператор присваивания. Экземпляр, которому назначено использование копирования по умолчанию, получит тот же указатель, что и экземпляр, создавший поверхность, на которую он указывает. Однажды один из них разрушает или звонит перерисовывать(), другой сохраняет указатель на свободную память, и это вызывает ошибку сегментации.
У меня есть класс для текстовых меток в моем приложении. Когда его свойства изменяются, он автоматически перерисовывается в свою личную поверхность.
Как правило, перерисовка выглядит так:
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).
Если исходить из того, что мы, как правило, знаем, что SDL работает хорошо, у нас остаются следующие варианты (я не могу думать ни о каких других, но вполне могут быть некоторые)
Поэтому я обычно отлаживаю это, добавляя некоторые (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);
}
Других решений пока нет …