Alexander Tkachov
Alexander Tkachov

Reputation: 43

Freeing a valid SDL surface results in segfault

[SOLVED] Forgot to implement a copy constructor and an assignment operator. The instance which is being assigned to using default copying will get the same pointer as the instance which created the surface it points to. Once one of them destructs or calls redraw(), the other keeps the pointer to freed memory, and it causes a segmentation fault.


I have a class for text labels in my application. When it's properties are changed, it automatically redrawing itself into it's private surface.

Generally, redrawing looks like this:

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

But the code crashing on freeing the surface (only a valid ones, of course, as the pointer equals to 0 when it doesn't have a surface to free).

It's also strange that on some machines the code's doing well and frees a memory. But on the others it crashes.

If I comment out lines where it frees a surface, the application works well, but the memory leaks. I didn't found nor explanation, neither a solution for that.


I do set _image to 0 in constructor. There is no code that changes _image value or frees the surface except redraw() function (and destructor).

Somehow freeing memory crashing on XP only. If I comment out freeing part, it doesn't crash. Both variants works on win7 (both x86 and x64) well.

Upvotes: 0

Views: 740

Answers (1)

Richard Harrison
Richard Harrison

Reputation: 19393

Taking the premise that that we generally know that SDL works well this leaves us with the following options (I can't think of any others, but there may well be some)

  • Possibility that the library was built incorrectly
  • The enclosing Text is somehow being copied somewhere else in the code (breaking the rule of 3
  • Something else is calling SDL_FreeSurface with the same pointer
  • Something else is trampling on the heap (possibly but unlikely as this is the only instance you've said that fails);

So I'd generally debug this by adding some (grep'able) printfs as follows and then check the output line by line:

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

Upvotes: 1

Related Questions