1
\$\begingroup\$

I am currently writing a pong clone in C++ with SDL on top. Currently, I have hit a roadblock. If I add a new variable, my game won't launch, and will give "segmentation fault" in the debug terminal.

When I comment out a variable, the following code gives no errors, but otherwise, it just returns "Segmentation Fault" on the debug terminal after flashing the frame the game would normally appear in.

#ifdef __cplusplus
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#ifdef __APPLE__
#include <SDL/SDL.h>
#else
#include <SDL.h>
#endif
#include "SDL/SDL_image.h"
#include "SDL/SDL_framerate.h"


#include "checkcol.h"

Uint8 *keystates = SDL_GetKeyState( NULL );

int main ( int argc, char** argv )
{
    // initialize SDL video
    if ( SDL_Init( SDL_INIT_EVERYTHING ) < 0 )
    {
        printf( "Unable to init SDL: %s\n", SDL_GetError() );
        return 1;
    }

    atexit(SDL_Quit);// make sure SDL cleans up before exit

    // create a new window
    SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16,SDL_HWSURFACE|SDL_DOUBLEBUF);
    if ( !screen )
    {
        printf("Unable to set 640x480 video: %s\n", SDL_GetError());
        return 1;
    }


    SDL_Surface* left = IMG_Load("left.png");
    SDL_Surface* right = IMG_Load("right.png");
    SDL_Surface* ball = IMG_Load("ball.png");

    if (!left||!right||!ball)
    {
        printf("Unable to load a png: %s\n", SDL_GetError());
        return 1;
    }

    // centre the bitmap on screen
    SDL_Rect leftr;
    leftr.x = 0;
    leftr.y = (screen->h - left->h) / 2;

    SDL_Rect rightr;
    rightr.x = (screen->w - right->w);
    rightr.y = (screen->h - right->h) / 2;

    SDL_Rect ball1;
    ball1.x = ((screen->w - ball->w) / 2)+50;
    ball1.y = (screen->h - ball->h) / 2;

    SDL_Rect ball2;
    ball2.x = ((screen->w - ball->w) / 2)-50;
    ball2.y = (screen->h - ball->h) / 2;

    bool b1xm=0;//describes ball 1's movement in x
    bool b1ym=0;
    bool b2xm=1;
    bool b2ym=1;

    unsigned short lscore=0;
    unsigned short rscore=0;


    FPSmanager * manex;

    SDL_initFramerate( manex );
    // you want the top framerate to be 60 for example
    SDL_setFramerate( manex, 60 );

    // program main loop
    bool done = false;
    while (!done)
    {
                         //this is where my main code is
    } // end main loop

    // free loaded images
    SDL_FreeSurface(left);
    SDL_FreeSurface(right);
    SDL_FreeSurface(ball);

    // all is well
    printf("Exited cleanly\n");
    return 0;
}
\$\endgroup\$
5
  • 3
    \$\begingroup\$ Question #1: why are you calling SDL_GetKeyState prior to your call to SDL_Init? You should not call ANYTHING else prior to SDL_Init. \$\endgroup\$ Mar 7, 2012 at 3:09
  • \$\begingroup\$ So, what variable are you adding that causes the crash, and where? \$\endgroup\$
    – thedaian
    Mar 7, 2012 at 3:10
  • \$\begingroup\$ @thedaian the variables lscore and rscore. \$\endgroup\$
    – earboxer
    Mar 7, 2012 at 3:14
  • \$\begingroup\$ @PlayDeezGames Thanks for the fix! (I'm surprised that didn't cause any problems) \$\endgroup\$
    – earboxer
    Mar 7, 2012 at 3:22
  • \$\begingroup\$ @PlayDeezGames +1 Do not call stuff like SDK_GetKeyState() in global space and a small FYI that atexit() is not guaranteed to be called in some cases leading to program termination so you may as well add that to your normal program exit flow. \$\endgroup\$ Mar 7, 2012 at 3:24

2 Answers 2

6
\$\begingroup\$

You are passing an unallocated pointer (manex) to a function that is expecting it to be allocated. In debug mode, you are passing (IIRC) the value 0xCDCDCDCD. In release, you are passing it a mystery value.

Take out the * between FPSmanager and manex, like so, and use the addressof operator:

FPSmanager manex = {0};
SDL_initFramerate(&manex);
SDL_setFramerate(&manex,60);

Chances are this is your actual problem, the other issue of variables perhaps just masking it.

Also, as I commented above, DO NOT call ANY other SDL function prior to your call to SDL_Init. You've been warned.

\$\endgroup\$
3
  • \$\begingroup\$ That {0} notation is new to me, except when used as an array initializer, which doesn't seem to be the case. Could you explain? \$\endgroup\$ Mar 7, 2012 at 14:35
  • \$\begingroup\$ you can use it to zero out the memory of a struct, making it unnecessary to do a memset. \$\endgroup\$ Mar 7, 2012 at 14:37
  • 2
    \$\begingroup\$ Specifically, it either initializes the first and only member of the struct to 0 or (if there are more members), initializes the first and value-initializes the remainder. Value initialization either calls the default ctor for the initialized type, zero-initializes the type, or value-initializes all elements (if the type is an array). This is covered in 8.5 of the C++ standard. \$\endgroup\$
    – user1430
    Mar 7, 2012 at 16:13
1
\$\begingroup\$
Uint8 *keystates = SDL_GetKeyState( NULL );

This is initialized at startup, even before your main() is called, thus it is called before SDL_Init.

Change it to:

Uint8 *keystates = 0;

and later on, in main() After the SDL_Init;

keystates = SDL_GetKeyState( NULL );
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .