Jump to content
  • Advertisement
Sign in to follow this  
mathall

Segmentation fault from SDL_LowerBlit ()

This topic is 2997 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm starting off with C++ and SDL, to help me learn I'm trying to create a small library to make using SDL easier (easy loading of files etc). I'm having a problem blitting to the screen, here is my code for surfaces, the screen and the test program:

//screen.cpp
#include "screen.h"
#include "surface.h"
#include "SDL/SDL.h"
#include <iostream>

SFrame_Screen::SFrame_Screen(int _width, int _height, int _bpp){
width = _width;
height = _height;
bpp = _bpp;
screen = SDL_SetVideoMode(width, height, bpp, SDL_SWSURFACE);
}

void SFrame_Screen::blit(int x, int y, SFrame_Surface source, SDL_Rect *clip){
std::cout << screen;
if(source.surface != NULL && screen != NULL){
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source.surface, clip, screen, &offset);
}
}

int SFrame_Screen::flip(){
if(screen != NULL){
return SDL_Flip(screen);
}
return -1;
}

void SFrame_Screen::fill(int r, int g, int B){
SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, r, g, B));
}






//surface.cpp
#include <string>
#include "surface.h"
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <iostream>

SFrame_Surface::SFrame_Surface(){
surface = NULL;
}

SFrame_Surface::SFrame_Surface(SDL_Surface *_surface){
surface = NULL;
surface = _surface;
}

SFrame_Surface::~SFrame_Surface(){
std::cout << "Freeing surface";
SDL_FreeSurface(surface);
}

SFrame_Image::SFrame_Image(std::string filename){
SDL_Surface *loadedImage = NULL;
SDL_Surface *optimizedImage = NULL;
loadedImage = IMG_Load(filename.c_str());
if( loadedImage != NULL )
{
optimizedImage = SDL_DisplayFormat(loadedImage);
SDL_FreeSurface(loadedImage);
}
surface = optimizedImage;
}

void SFrame_Image::set_colour_key(int r, int g, int B){
Uint32 colorkey = SDL_MapRGB(surface->format, r, g, B);
SDL_SetColorKey(surface, SDL_SRCCOLORKEY, colorkey);
}






//test code
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "sframe.h"
#include <string>
#include <iostream>

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

SDL_Surface *image = NULL;

SDL_Event event;

SFrame_Screen init()
{
SDL_Init( SDL_INIT_EVERYTHING );
SFrame_Screen screen(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP);
SDL_WM_SetCaption( "Test", NULL );
TTF_Init();

return screen;
}

void clean_up()
{
TTF_Quit();
SDL_Quit();
}

int main( int argc, char* args[] )
{
bool quit = false;

if(!sframe_init_everything()){
return 1;
}
SFrame_Screen screen(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP);
SDL_WM_SetCaption( "Test", NULL );

SFrame_Image image("foo.png");
image.set_colour_key(0, 0xFF, 0xFF);
SFrame_Font font("lazy.ttf", 28);
SDL_Color text_colour = { 0, 0, 0 };
SFrame_Surface text = font.render("Hello, world", text_colour);

while( quit == false )
{
while( SDL_PollEvent( &event ) )
{
if( event.type == SDL_QUIT )
{
quit = true;
}
}
screen.fill(255,255,255);
screen.blit(0, 0, image);
screen.blit(300,200,text);
if( screen.flip() == -1 )
{
return 1;
}
}

sframe_clean_up();

return 0;
}





When I compile all this and run it the screen comes and then disappears and I get a segmentation fault. I then loaded it with gdb, here's the backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x0015df83 in SDL_LowerBlit () from /usr/lib/libSDL-1.2.so.0
(gdb) backtrace
#0 0x0015df83 in SDL_LowerBlit () from /usr/lib/libSDL-1.2.so.0
#1 0x0015e242 in SDL_UpperBlit () from /usr/lib/libSDL-1.2.so.0
#2 0x0012f439 in SFrame_Screen::blit (this=0xbffff2d8, x=0, y=0, source=...,
clip=0x0) at screen.cpp:19
#3 0x080491ac in main (argc=1, args=0xbffff3e4) at test_sdl.cpp:57


I also ran it through valgrind, it said that a surface's destructor method had been called:

==3789== Invalid read of size 4
==3789== at 0x4076F80: SDL_LowerBlit (in /usr/lib/libSDL-1.2.so.0.11.3)
==3789== by 0x4077241: SDL_UpperBlit (in /usr/lib/libSDL-1.2.so.0.11.3)
==3789== by 0x4047438: SFrame_Screen::blit(int, int, SFrame_Surface, SDL_Rect*) (screen.cpp:19)
==3789== by 0x804914B: main (test_sdl.cpp:57)
==3789== Address 0x492b030 is 48 bytes inside a block of size 60 free'd
==3789== at 0x4024B3A: free (vg_replace_malloc.c:366)
==3789== by 0x4076A15: SDL_FreeSurface (in /usr/lib/libSDL-1.2.so.0.11.3)
==3789== by 0x4047108: SFrame_Surface::~SFrame_Surface() (surface.cpp:18)
==3789== by 0x8049156: main (test_sdl.cpp:57)


Why has it been destroyed and why has it crashed? (All the variables seemed ok...)

EDIT: Full code @ http://filebin.ca/vmkyuy/sdl_framework.zip

Share this post


Link to post
Share on other sites
Advertisement
In SFrame_Screen::blit(), you are passing the source surface by value. This is a problem since SFrame_Surface doesn't have a proper copy constructor. Pass it by reference, and disallow copy/assignment for SFrame_Surface.

You can do that by declaring the copy constructor and assignment operator as private. You don't even need to implement them:


class SFrame_Surface {
private:
SFrame_Surface(const SFrame_Surface &);
const SFrame_Surface & operator=(const SFrame_Surface &);
};

Share this post


Link to post
Share on other sites
Quote:
Original post by Gage64
In SFrame_Screen::blit(), you are passing the source surface by value. This is a problem since SFrame_Surface doesn't have a proper copy constructor. Pass it by reference, and disallow copy/assignment for SFrame_Surface.

You can do that by declaring the copy constructor and assignment operator as private. You don't even need to implement them:

*** Source Snippet Removed ***


Thanks for your quick reply. Do you mean pass source.surface by reference:

SDL_BlitSurface(&source.surface, clip, screen, &offset);


? And what should the surface class look like?

class SFrame_Surface {
private:
SFrame_Surface(const SFrame_Surface &);
const SFrame_Surface & operator=(const SFrame_Surface &);
public:
SFrame_Surface(){};
//SFrame_Surface(SDL_Surface *_surface);
~SFrame_Surface();
SDL_Surface *surface;
};



Sorry for being such a noob! I better go read up on C/C++ again ;)

Share this post


Link to post
Share on other sites
I meant that you should change this line:

void SFrame_Screen::blit(int x, int y, SFrame_Surface source, SDL_Rect *clip){

to this:

void SFrame_Screen::blit(int x, int y, SFrame_Surface &source, SDL_Rect *clip){

Notice I added a & before 'source'. This is called a reference and you can read more about it here.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!