Zacariaz
Zacariaz

Reputation: 567

Odd segmentation fault with CC/GCC but not G++ (C/SDL2/Linux)

The code posted is copied directly from an example of a popular SDL2 tutorial, to ensure that it wasn't I who had made some silly mistake. All I've done to the example is changing the path of the image file in question, I changed type bool to int, false to 0 and true to 1. As I understand it, nothing C++ specific should remain.

Everything seems to work regardless what I do, but when compiling with CC/GCC (I suppose that's really the same deal) I get a segmentation fault in the very end, I suspect in close(), which I've been unable to determine. Compiling with G++ somehow prevents the segmentation fault.

The solution of course is simple, just use G++, but I would very much like to know wherein the problem lies.

main.c:

//Using SDL and standard IO
#include <SDL2/SDL.h>
#include <stdio.h>

//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

//Starts up SDL and creates window
int init();

//Loads media
int loadMedia();

//Frees media and shuts down SDL
void close();

//The window we'll be rendering to
SDL_Window* gWindow = NULL;

//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;

//The image we will load and show on the screen
SDL_Surface* gHelloWorld = NULL;

int init()
{
    //Initialization flag
    int success = 1;

    //Initialize SDL
    if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
        success = 0;
    }
    else
    {
        //Create window
        gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED,
                                    SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH,
                                    SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
        if( gWindow == NULL )
        {
            printf( "Window could not be created! SDL_Error: %s\n",
                    SDL_GetError() );
            success = 0;
        }
        else
        {
            //Get window surface
            gScreenSurface = SDL_GetWindowSurface( gWindow );
        }
    }

    return success;
}

int loadMedia()
{
    //Loading success flag
    int success = 1;

    //Load splash image
    gHelloWorld = SDL_LoadBMP( "hello_world.bmp" );
    if( gHelloWorld == NULL )
    {
        printf( "Unable to load image %s! SDL Error: %s\n", "hello_world.bmp",
                SDL_GetError() );
        success = 0;
    }

    return success;
}

void close()
{
    //Deallocate surface
    SDL_FreeSurface( gHelloWorld );
    gHelloWorld = NULL;

    //Destroy window
    SDL_DestroyWindow( gWindow );
    gWindow = NULL;

    //Quit SDL subsystems
    SDL_Quit();
}

int main( int argc, char* args[] )
{
    //Start up SDL and create window
    if( !init() )
    {
        printf( "Failed to initialize!\n" );
    }
    else
    {
        //Load media
        if( !loadMedia() )
        {
            printf( "Failed to load media!\n" );
        }
        else
        {
            //Apply the image
            SDL_BlitSurface( gHelloWorld, NULL, gScreenSurface, NULL );

            //Update the surface
            SDL_UpdateWindowSurface( gWindow );

            //Wait two seconds
            SDL_Delay( 2000 );
        }
    }

    //Free resources and close SDL
    close();

    return 0;
}

I don't see how it's relevant, but just to be on the safe side, here's the standard Makefile I'm using

#OBJS specifies which files to compile as part of the project
OBJS = main.c

#CC specifies which compiler we're using
CC = cc

#COMPILER_FLAGS specifies the additional compilation options we're using
# -w suppresses all warnings
COMPILER_FLAGS = -Wall -Wextra -pedantic

#LINKER_FLAGS specifies the libraries we're linking against
LINKER_FLAGS = -lSDL2

#OBJ_NAME specifies the name of our exectuable
OBJ_NAME = test

#This is the target that compiles our executable
all : $(OBJS)
    $(CC) $(OBJS) $(COMPILER_FLAGS) $(LINKER_FLAGS) -o $(OBJ_NAME)

I get no errors or warnings but unused argv and argc.

At this point I'm at a dead end, thus I ask here.

Best regards.

NB: I should be mentioned that whatever the issue, it's most definitely not a hardware issue, various search results have suggested, as I get the exact same result and problem, on two entirely different hardware platforms.

Upvotes: 4

Views: 702

Answers (1)

yngccc
yngccc

Reputation: 5684

If you rename the function close() the segfault goes away, looks like init() calls into SDL which calls into X11 which calls into your driver which calls close(), but instead of calling the right close() it calls yours instead. In C++ functions will get name mangled to something else so it it not a problem.

Upvotes: 7

Related Questions