Hello, I'm new to programming, and I'm trying to learn SDL using (mostly) LazyFoo's tutorials.

I'm using Code::Blocks in Windows XP, and when trying to run my program, it returns 3. The code is below, I think the problem is in the loadf() function, but I can't find it.

I tried to use the debugger, which gives me the message below:

Code:
Program received signal SIGSEGV, Segmentation fault. In ?? () ()

If I'm not mistaken, this message means that the program is referencing a rogue pointer, or generally a piece of memory it is not supposed to. But I check my code again and again, and I can't find where the problem is.

The files work perfectly in my previous simpler programs, and the load() and loadf() code is nearly identical.

I'm really not very experienced, since I only started learning programming about two months ago, and some help with this would really be appreciated.

Please excuse the length of the code. I post all of it here because I don't know what function the problem is in.

Thank you in advance.


Code:
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include "SDL/SDL_mixer.h"
#include <string>

const int SW = 640;
const int SH = 480;
const int BPP = 32;

SDL_Surface * screen = NULL;
SDL_Surface * background = NULL;
SDL_Surface * faces = NULL;
SDL_Surface * text = NULL;

Mix_Chunk * up = NULL;
Mix_Chunk * down = NULL;
Mix_Chunk * left = NULL;
Mix_Chunk * right = NULL;

SDL_Rect clip[5];

SDL_Event event;

TTF_Font * font = NULL;
SDL_Color tcolor = { 255 , 255 , 255 };

bool init()
{
    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
    {
        return false;
    }

    screen = SDL_SetVideoMode( SW , SH , BPP , SDL_SWSURFACE );

    if( screen == NULL || TTF_Init() == -1 )
    {
        return false;
    }

    if( Mix_OpenAudio( 22050 , MIX_DEFAULT_FORMAT , 2 , 4096 ) == -1 )
    {
        return false;
    }

    SDL_WM_SetCaption( "Directions w/ sound!" , NULL );

    return true;
}

void clean()
{
    SDL_FreeSurface( background );
    SDL_FreeSurface( faces );
    SDL_FreeSurface( text );

    Mix_FreeChunk( up );
    Mix_FreeChunk( down );
    Mix_FreeChunk( left );
    Mix_FreeChunk( right );
    Mix_CloseAudio();

    TTF_CloseFont( font );
    TTF_Quit();

    SDL_Quit();
}

SDL_Surface * load( std::string file )
{
    SDL_Surface * loaded = NULL;
    SDL_Surface * optimized = NULL;

    loaded = IMG_Load( file.c_str() );

    if( loaded != NULL )
    {
        optimized = SDL_DisplayFormatAlpha( loaded );
        SDL_FreeSurface( loaded );
    }

    return optimized;
}

bool loadf()
{
    background = load( "bg.png" );
    faces = load( "d.png" );
    font = TTF_OpenFont( "Qarmic_sans_Abridged.ttf" , 24 );

    if( background == NULL )
    {
        return false;
    }

    if( faces == NULL )
    {
        return false;
    }

    if( font == NULL )
    {
        return false;
    }

    up = Mix_LoadWAV( "up.wav" );
    down = Mix_LoadWAV( "down.wav" );
    left = Mix_LoadWAV( "left.wav" );
    right = Mix_LoadWAV( "right.wav" );

    if( up == NULL || down == NULL || left == NULL || right == NULL )
    {
        return false;
    }

    return true;
}

void apply( int x , int y , SDL_Surface * get = NULL , SDL_Surface * give = NULL , SDL_Rect * clips = NULL )
{
    SDL_Rect off;

    off.x = x;
    off.y = y;

    SDL_BlitSurface( get , clips , give , &off );
}

void clipping()
{
    clip[0].x = 0;
    clip[0].y = 0;
    clip[0].w = 100;
    clip[0].h = 100;

    clip[1].x = 100;
    clip[1].y = 0;
    clip[1].w = 100;
    clip[1].h = 100;

    clip[2].x = 0;
    clip[2].y = 100;
    clip[2].w = 100;
    clip[2].h = 100;

    clip[3].x = 100;
    clip[3].y = 100;
    clip[3].w = 100;
    clip[3].h = 100;

    clip[4].x = 0;
    clip[4].y = 200;
    clip[4].w = 100;
    clip[4].h = 100;
}

int run( int num , std::string direct , int fw , int fh , int tw , int th )
{
    text = TTF_RenderText_Solid( font , direct.c_str() , tcolor );

    if( text != NULL )
    {
        apply( 0 , 0 , background , screen );
        apply( fw , fh , faces , screen , &clip[num] );
        apply( tw , th , text , screen );
    }

    if( SDL_Flip( screen ) == -1 )
    {
        return 1;
    }
}

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

    if( init() == false )
    {
        return 2;
    }

    if( loadf() == false )
    {
        return 3;
    }

    if( clip != NULL )
    {
        clipping();
    }

    run( 0 , "Center!" , 290 , 180 , ( SW - text->w ) / 2 , 290 );

    while( quit == false )
    {
        while( SDL_PollEvent( &event ) )
        {
            if( event.type == SDL_QUIT )
            {
                quit = true;
            }
        }

        Uint8 * keys = SDL_GetKeyState( NULL );

        if( keys[SDLK_UP] )
        {
            run( 1 , "Up!" , 290 , 10 , ( SW - text->w ) / 2 , 120 );

            if( Mix_PlayChannel( -1 , up , 0 ) == -1 )
            {
                return 4;
            }
        }

        if( keys[SDLK_DOWN] )
        {
            run( 2 , "Down!" , 290 , 500 , ( SW - text->w ) / 2 , 600 );

            if( Mix_PlayChannel( -1 , down , 0 ) == -1 )
            {
                return 4;
            }
        }

        if( keys[SDLK_LEFT] )
        {
            run( 3 , "Left!" , 10 , 190 , 10 , 290 );

            if( Mix_PlayChannel( -1 , left , 0 ) == -1 )
            {
                return 4;
            }
        }

        if( keys[SDLK_RIGHT] )
        {
            run( 4 , "Right!" , 370 , 190 , 370 , 290 );

            if( Mix_PlayChannel( -1 , right , 0 ) )
            {
                return 4;
            }
        }

        if( keys[SDLK_SPACE] )
        {
            run( 0 , "Center!" , 290 , 180 , ( SW - text->w ) / 2 , 290 );
        }
    }

    clean();

    return 0;
}