SDL_RendererPresent resulting in SIGSEV

I’m making a game in SDL, and it works fine and dandy up until it handles rendering, where then it gets to the SDL_RenderPresent line and then it SIGSEVs. SDL_RenderClear works perfectly fine, just not SDL_RenderPresent.

Here’s the code

#include <iostream>
#include <SDL2/SDL.h>

#define FAIL false
#define SUCESS true

SDL_Texture* textures[5];

bool createWindow(SDL_Window* window, SDL_Renderer* renderer)
{
    SDL_Init(SDL_INIT_VIDEO || SDL_INIT_AUDIO);

    window = SDL_CreateWindow("YonKaGor Gambling", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1920, 1080, SDL_WINDOW_SHOWN);
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

    if(!window || !renderer)
    {
        std::cout << "The program failed because: " << SDL_GetError() << std::endl;

        return FAIL;
    }

    return SUCESS;
}

void stopProgram(SDL_Window* window, bool* running)
{
    SDL_DestroyWindow(window);

    for(int i = 0; i < 10; i++)
    {

    }

    *running = false;
}

void getEvents(SDL_Window* window, bool* runningPointer)
{
    SDL_Event event;

    SDL_PollEvent(&event);

    switch(event.type)
    {
        case SDL_QUIT:
            stopProgram(window, runningPointer);
    }
}

void prepareNextFrame()
{

}

void renderFrame(SDL_Renderer* renderer)
{
    SDL_RenderClear(renderer);

    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);

    SDL_RenderPresent(renderer);
}

int main()
{
    SDL_Window* window;
    SDL_Renderer* renderer;

    bool running = true;

    bool* runningPointer;

    runningPointer = &running;

    if(createWindow(window, renderer) == FAIL)
    {
        stopProgram(window, runningPointer);
    }

    while(running)
    {
        getEvents(window, runningPointer);
        prepareNextFrame();
        renderFrame(renderer);
    }
}

And here’s the output:

Breakpoint 1, main () at main.cpp:66
66 {
(gdb) step
70 bool running = true;
(gdb) step
74 runningPointer = &running;
(gdb) step
76 if(createWindow(window, renderer) == FAIL)
(gdb) step
createWindow (window=0x7ffff7811ac0 <main_arena>, renderer=0x1) at main.cpp:11
11 SDL_Init(SDL_INIT_VIDEO || SDL_INIT_AUDIO);
(gdb) step
[New Thread 0x7fffea1ff6c0 (LWP 53613)]
13 window = SDL_CreateWindow(“YonKaGor Gambling”, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1920, 1080, SDL_WINDOW_SHOWN);
(gdb) step
14 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
(gdb) step
[New Thread 0x7fffe92066c0 (LWP 53624)]
[New Thread 0x7fffe8a056c0 (LWP 53625)]
[New Thread 0x7fffe3fff6c0 (LWP 53626)]
[New Thread 0x7fffe37fe6c0 (LWP 53627)]
[Thread 0x7fffe37fe6c0 (LWP 53627) exited]
[Thread 0x7fffe3fff6c0 (LWP 53626) exited]
[New Thread 0x7fffe3fff6c0 (LWP 53628)]
[New Thread 0x7fffe37fe6c0 (LWP 53629)]
16 if(!window || !renderer)
(gdb) step
23 return SUCESS;
(gdb) step
24 }
(gdb) step
main () at main.cpp:81
81 while(running)
(gdb) step
83 getEvents(window, runningPointer);
(gdb) step
getEvents (window=0x7ffff7811ac0 <main_arena>, runningPointer=0x7fffffffd80f) at main.cpp:39
39 {
(gdb) step
42 SDL_PollEvent(&event);
(gdb) step
44 switch(event.type)
(gdb) step
49 }
(gdb) step
main () at main.cpp:84
84 prepareNextFrame();
(gdb) step
prepareNextFrame () at main.cpp:54
54 }
(gdb) step
main () at main.cpp:85
85 renderFrame(renderer);
(gdb) step
renderFrame (renderer=0x1) at main.cpp:58
58 SDL_RenderClear(renderer);
(gdb) step

Thread 1 “Yonkagor Gambli” received signal SIGSEGV, Segmentation fault.
0x00007ffff7e1c73c in ?? () from /lib/x86_64-linux-gnu/libSDL2-2.0.so.0

GCC says:

test.cpp: In function ‘int main()’:
test.cpp:76:20: warning: ‘window’ is used uninitialized in this function [-Wuninitialized]
     if(createWindow(window, renderer) == FAIL)
        ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
test.cpp:76:20: warning: ‘renderer’ is used uninitialized in this function [-Wuninitialized]
...

If you’re using GCC, I think you should at least use -Wall. It enables this and many other useful warnings.

This is also wrong:

SDL_Init(SDL_INIT_VIDEO || SDL_INIT_AUDIO);

To combine bit flags you want to use bitwise or (|), not logical or (||).

SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); // this is correct

I tried doing that as a way to do it without using global variables, since I heard they can make performance worse. So, are global variables fine or should I find a work around?

You’re passing the pointers by value which means that modifications made to the pointers inside the function won’t affect the pointers in main. To allow the function to affect the pointers in main you would have to pass them by reference instead (or pass pointers to the pointers).

I don’t think performance is a big reason why people don’t use globals. It’s more about making the code easier to reason about. If you use globals instead of passing things as arguments it becomes less clear what data the functions rely on, and it becomes more difficult making things independent and reusable.

A compromise, to avoid having to pass a lot of variables everywhere, is to group things into objects and pass the objects instead. Not sure it’s the best way to do it, but in my games I usually have a big “game object” that encapsulates most things, although I have to admit that I do end up with some globals/singletons too.

Another thing is this function:

You should first set the color, then clear the rendering target, in this way:

void renderFrame(SDL_Renderer* renderer)
{
    // Clear the rendering target with opaque white.
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderClear(renderer);

    // Update image on the screen.
    SDL_RenderPresent(renderer);
}

How do I pass the pointers in a way that lets me edit the ones in main?

By reference:

bool createWindow(SDL_Window*& window, SDL_Renderer*& renderer)

The call site and function body remains the same.

This is the “C++ way” of doing it.


Or by using pointers to pointers:

bool createWindow(SDL_Window** window, SDL_Renderer** renderer)
{
    ...
    *window = SDL_CreateWindow("YonKaGor Gambling", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1920, 1080, SDL_WINDOW_SHOWN);
    *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    ...
}
if (createWindow(&window, &renderer) == FAIL)

This is more the “C way” of doing it (because C doesn’t have references). SDL is written in C so it uses this technique in a few places, e.g. in SDL_CreateWindowAndRenderer. It can also be used if you want some of the arguments to be optional (in which case you would pass null), like in SDL_GetWindowSize.

lol

If you don’t know how to use global variables properly they can quickly become a problem I wrote an article on how I like to use them. You might need to read the article after it to understand the one on globals better. They’re at the bottom

1 Like