# \[SDL 3.1.6\] Memory leeks

**URL:** <https://discourse.libsdl.org/t/sdl-3-1-6-memory-leeks/55851>\
**Category:** SDL Development\
**Created:** [December 7, 2024, 2:10pm UTC](https://discourse.libsdl.org/t/sdl-3-1-6-memory-leeks/55851 "2024-12-07T14:10:23Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mathias](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/m/bbe5ce/32.png) [@Mathias](https://discourse.libsdl.org/u/Mathias)\
**Post date:** [December 7, 2024, 2:10pm UTC](https://discourse.libsdl.org/t/sdl-3-1-6-memory-leeks/55851/1 "2024-12-07T14:10:23Z")

</div>

I tested the following program, which is actually nothing special.

I tested it with `valgrind --leak-check=full ./main`. Why am I getting so many errors?

```auto
/*
  Linux:
  gcc main.c -o main -lSDL3

  Windows:
  x86_64-w64-mingw32-gcc main.c -o main.exe -lSDL3 -I/usr/local/include -L/usr/local/bin
*/

#include <SDL3/SDL.h>

int main(int argc, char* argv[]) {
    SDL_Init(SDL_INIT_VIDEO);   
    SDL_Window *window = SDL_CreateWindow("An SDL3 window", 640, 480, SDL_WINDOW_OPENGL);
    SDL_Delay(3000);  
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

```

Output:

```auto
$ valgrind --leak-check=full ./main 
==2878== Memcheck, a memory error detector
==2878== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==2878== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==2878== Command: ./main
==2878== 
==2878== 
==2878== HEAP SUMMARY:
==2878== in use at exit: 350,549 bytes in 3,376 blocks
==2878== total heap usage: 24,139 allocs, 20,763 frees, 6,086,239 bytes allocated
==2878== 
==2878== 29 bytes in 1 blocks are definitely lost in loss record 158 of 2,366
==2878== at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==2878== by 0x5374F93: ???
==2878== by 0x535AAE7: ???
==2878== by 0x4B27296: SDL_DBus_Init (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48B26D7: SDL_InitSubSystem_REAL (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48B2A2E: SDL_Init_REAL (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48E1160: SDL_Init_DEFAULT (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48EE940: SDL_Init (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x1091E5: main (in /n4800/DATEN/Programmierung/mit_GIT/Lazarus/Tutorial/SDL-3/Versuche/C/native_C/SDL3_CreateWindow/main)
==2878== 
==2878== 29 bytes in 1 blocks are definitely lost in loss record 159 of 2,366
==2878== at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==2878== by 0x5374F93: ???
==2878== by 0x535AAAA: ???
==2878== by 0x4B27296: SDL_DBus_Init (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48B26D7: SDL_InitSubSystem_REAL (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48B2A2E: SDL_Init_REAL (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48E1160: SDL_Init_DEFAULT (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48EE940: SDL_Init (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x1091E5: main (in /n4800/DATEN/Programmierung/mit_GIT/Lazarus/Tutorial/SDL-3/Versuche/C/native_C/SDL3_CreateWindow/main)
==2878== 
==2878== 38 bytes in 1 blocks are definitely lost in loss record 946 of 2,366
==2878== at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==2878== by 0x5374F93: ???
==2878== by 0x535A8D9: ???
==2878== by 0x4B27296: SDL_DBus_Init (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48B26D7: SDL_InitSubSystem_REAL (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48B2A2E: SDL_Init_REAL (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48E1160: SDL_Init_DEFAULT (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48EE940: SDL_Init (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x1091E5: main (in /n4800/DATEN/Programmierung/mit_GIT/Lazarus/Tutorial/SDL-3/Versuche/C/native_C/SDL3_CreateWindow/main)
==2878== 
==2878== 72 (24 direct, 48 indirect) bytes in 1 blocks are definitely lost in loss record 2,302 of 2,366
==2878== at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==2878== by 0x537CD95: ???
==2878== by 0x5367A45: ???
==2878== by 0x536CD6E: ???
==2878== by 0x535A1B2: ???
==2878== by 0x535A43B: ???
==2878== by 0x535A707: ???
==2878== by 0x4B27296: SDL_DBus_Init (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48B26D7: SDL_InitSubSystem_REAL (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48B2A2E: SDL_Init_REAL (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48E1160: SDL_Init_DEFAULT (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48EE940: SDL_Init (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== 
==2878== 520 bytes in 13 blocks are definitely lost in loss record 2,337 of 2,366
==2878== at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==2878== by 0x5378C8B: ???
==2878== by 0x536C934: ???
==2878== by 0x4B27269: SDL_DBus_Init (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48B26D7: SDL_InitSubSystem_REAL (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48B2A2E: SDL_Init_REAL (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48E1160: SDL_Init_DEFAULT (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48EE940: SDL_Init (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x1091E5: main (in /n4800/DATEN/Programmierung/mit_GIT/Lazarus/Tutorial/SDL-3/Versuche/C/native_C/SDL3_CreateWindow/main)
==2878== 
==2878== 727 (184 direct, 543 indirect) bytes in 1 blocks are definitely lost in loss record 2,341 of 2,366
==2878== at 0x484D953: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==2878== by 0x5366DDF: ???
==2878== by 0x5367BF4: ???
==2878== by 0x535A41C: ???
==2878== by 0x535A707: ???
==2878== by 0x4B27296: SDL_DBus_Init (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48B26D7: SDL_InitSubSystem_REAL (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48B2A2E: SDL_Init_REAL (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48E1160: SDL_Init_DEFAULT (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x48EE940: SDL_Init (in /usr/local/lib/libSDL3.so.0.1.7)
==2878== by 0x1091E5: main (in /n4800/DATEN/Programmierung/mit_GIT/Lazarus/Tutorial/SDL-3/Versuche/C/native_C/SDL3_CreateWindow/main)
==2878== 
==2878== 2,302 (736 direct, 1,566 indirect) bytes in 4 blocks are definitely lost in loss record 2,354 of 2,366
==2878== at 0x484D953: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==2878== by 0x5366DDF: ???
==2878== by 0x5368D6D: ???
==2878== by 0x53718DB: ???
==2878== by 0x5371AAF: ???
==2878== by 0x5372BE0: ???
==2878== by 0x53731CF: ???
==2878== by 0x5358391: ???
==2878== by 0x536D04C: ???
==2878== by 0x535A19D: ???
==2878== by 0x535A43B: ???
==2878== by 0x535A707: ???
==2878== 
==2878== LEAK SUMMARY:
==2878== definitely lost: 1,560 bytes in 22 blocks
==2878== indirectly lost: 2,157 bytes in 12 blocks
==2878== possibly lost: 0 bytes in 0 blocks
==2878== still reachable: 346,832 bytes in 3,342 blocks
==2878== suppressed: 0 bytes in 0 blocks
==2878== Reachable blocks (those to which a pointer was found) are not shown.
==2878== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==2878== 
==2878== For lists of detected and suppressed errors, rerun with: -s
==2878== ERROR SUMMARY: 7 errors from 7 contexts (suppressed: 0 from 0)

```

---

<div class="post-metadata">

**Author:** ![slouken](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/s/ec9cab/32.png) [@slouken](https://discourse.libsdl.org/u/slouken)\
**Post date:** [December 7, 2024, 2:50pm UTC](https://discourse.libsdl.org/t/sdl-3-1-6-memory-leeks/55851/2 "2024-12-07T14:50:40Z")

</div>

We leave D-bus active so that your program doesn’t crash if other parts of your application are still using it after SDL\_Quit().

You can do a full D-bus cleanup by calling:

```c
SDL_SetHint(SDL_HINT_SHUTDOWN_DBUS_ON_QUIT, "1");

```

or setting the environment variable SDL\_SHUTDOWN\_DBUS\_ON\_QUIT=1

---

<div class="post-metadata">

**Author:** ![Mathias](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/m/bbe5ce/32.png) [@Mathias](https://discourse.libsdl.org/u/Mathias)\
**Post date:** [December 7, 2024, 6:11pm UTC](https://discourse.libsdl.org/t/sdl-3-1-6-memory-leeks/55851/3 "2024-12-07T18:11:43Z")

</div>

Now the memory leak is gone. Thanks.  
I had to rewrite Set(h)int.

```auto
int main(int argc, char* argv[]) {
  SDL_SetHint(SDL_HINT_SHUTDOWN_DBUS_ON_QUIT, "1");
  SDL_Init(SDL_INIT_VIDEO);
  SDL_Window *window = SDL_CreateWindow("An SDL3 window", 640, 480, SDL_WINDOW_OPENGL);
  SDL_Delay(3000);
  SDL_DestroyWindow(window);
  SDL_Quit();
  return 0;
}

```

---

<div class="post-metadata">

**Author:** ![Harbour](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/h/0ea827/32.png) [@Harbour](https://discourse.libsdl.org/u/Harbour)\
**Post date:** [December 8, 2024, 8:09am UTC](https://discourse.libsdl.org/t/sdl-3-1-6-memory-leeks/55851/4 "2024-12-08T08:09:46Z")

</div>

> [@slouken](#):
>
> `SDL_SetHint(SDL_HINT_SHUTDOWN_DBUS_ON_QUIT, "1");`

I compiled the user’s example, and initially, Valgrind reported 10 memory leaks. After adding the following line to the code, the number of leaks was reduced to two. What else can I do to completely eliminate these remaining leaks related to SDL\_DBus\_Init?

```auto
==4724== Memcheck, a memory error detector
==4724== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==4724== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==4724== Command: ./main
==4724== 
==4724== 
==4724== HEAP SUMMARY:
==4724== in use at exit: 355,621 bytes in 3,398 blocks
==4724== total heap usage: 24,659 allocs, 21,261 frees, 5,903,086 bytes allocated
==4724== 
==4724== 8 bytes in 1 blocks are definitely lost in loss record 11 of 2,399
==4724== at 0x484DB80: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4724== by 0x53695C1: ???
==4724== by 0x5352D8C: ???
==4724== by 0x5356390: ???
==4724== by 0x5356707: ???
==4724== by 0x4B0ADFE: SDL_DBus_Init (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==4724== by 0x489076C: SDL_InitSubSystem_REAL (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==4724== by 0x4890ACF: SDL_Init_REAL (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==4724== by 0x48CCCC7: SDL_Init (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==4724== by 0x10921E: main (in /home/harbour/Dokumenty/hbsdl3/tests/main)
==4724== 
==4724== 8,765 (40 direct, 8,725 indirect) bytes in 1 blocks are definitely lost in loss record 2,395 of 2,399
==4724== at 0x484D953: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4724== by 0x53713B9: ???
==4724== by 0x5378456: ???
==4724== by 0x53784D7: ???
==4724== by 0x5378544: ???
==4724== by 0x534DC68: ???
==4724== by 0x535522D: ???
==4724== by 0x53566F0: ???
==4724== by 0x4B0ADFE: SDL_DBus_Init (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==4724== by 0x489076C: SDL_InitSubSystem_REAL (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==4724== by 0x4890ACF: SDL_Init_REAL (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==4724== by 0x48CCCC7: SDL_Init (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==4724== 
==4724== LEAK SUMMARY:
==4724== definitely lost: 48 bytes in 2 blocks
==4724== indirectly lost: 8,725 bytes in 54 blocks
==4724== possibly lost: 0 bytes in 0 blocks
==4724== still reachable: 346,848 bytes in 3,342 blocks
==4724== suppressed: 0 bytes in 0 blocks
==4724== Reachable blocks (those to which a pointer was found) are not shown.
==4724== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==4724== 
==4724== For lists of detected and suppressed errors, rerun with: -s
==4724== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

```

**First leak:**

- 8 bytes in 1 block.
- The call originates from the `realloc` function and ultimately from `SDL_DBus_Init`.
- Label: “definitely lost” (definitely lost).

**Second leak:**

- 8,765 bytes (40 bytes “directly lost” and 8,725 bytes “indirectly lost”).
- The call originates from the `calloc` function in `SDL_DBus_Init`.
- Label: “definitely lost” (definitely lost).

Sorry, I forgot to add that for Version: 3.1.7.

---

<div class="post-metadata">

**Author:** ![slouken](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/s/ec9cab/32.png) [@slouken](https://discourse.libsdl.org/u/slouken)\
**Post date:** [December 8, 2024, 4:32pm UTC](https://discourse.libsdl.org/t/sdl-3-1-6-memory-leeks/55851/5 "2024-12-08T16:32:11Z")

</div>

I’m not sure, can you get the libdbus symbols so we can get a full stack trace inside that library?

---

<div class="post-metadata">

**Author:** ![Harbour](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/h/0ea827/32.png) [@Harbour](https://discourse.libsdl.org/u/Harbour)\
**Post date:** [December 8, 2024, 10:28pm UTC](https://discourse.libsdl.org/t/sdl-3-1-6-memory-leeks/55851/6 "2024-12-08T22:28:51Z")

</div>

Below is the relevant part of the output showing memory leaks in `SDL_DBus_Init` within `libSDL3.so`. The symbols are now available, and it seems the issue is related to how `SDL_DBus_Init` handles memory.

```auto
==52659== 
==52659== HEAP SUMMARY:
==52659== in use at exit: 355,623 bytes in 3,398 blocks
==52659== total heap usage: 24,659 allocs, 21,261 frees, 5,903,100 bytes allocated
==52659== 
==52659== 8 bytes in 1 blocks are definitely lost in loss record 11 of 2,399
==52659== at 0x484DB80: realloc (vg_replace_malloc.c:1690)
==52659== by 0x536A5C1: ???
==52659== by 0x5353D8C: ???
==52659== by 0x5357390: ???
==52659== by 0x5357707: ???
==52659== by 0x4B0B5E3: SDL_DBus_Init (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==52659== by 0x489076C: SDL_InitSubSystem_REAL (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==52659== by 0x4890ACF: SDL_Init_REAL (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==52659== by 0x48CCD4C: SDL_Init (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==52659== by 0x10921E: main (in /home/harbour/Dokumenty/hbsdl3/tests/main)
==52659== 
==52659== 8,767 (40 direct, 8,727 indirect) bytes in 1 blocks are definitely lost in loss record 2,395 of 2,399
==52659== at 0x484D953: calloc (vg_replace_malloc.c:1595)
==52659== by 0x53723B9: ???
==52659== by 0x5379456: ???
==52659== by 0x53794D7: ???
==52659== by 0x5379544: ???
==52659== by 0x534EC68: ???
==52659== by 0x535622D: ???
==52659== by 0x53576F0: ???
==52659== by 0x4B0B5E3: SDL_DBus_Init (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==52659== by 0x489076C: SDL_InitSubSystem_REAL (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==52659== by 0x4890ACF: SDL_Init_REAL (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==52659== by 0x48CCD4C: SDL_Init (in /home/harbour/SDL/build/libSDL3.so.0.1.7)
==52659== 
==52659== LEAK SUMMARY:
==52659== definitely lost: 48 bytes in 2 blocks
==52659== indirectly lost: 8,727 bytes in 54 blocks
==52659== possibly lost: 0 bytes in 0 blocks
==52659== still reachable: 346,848 bytes in 3,342 blocks
==52659== suppressed: 0 bytes in 0 blocks
==52659== Reachable blocks (those to which a pointer was found) are not shown.
==52659== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==52659== 
==52659== For lists of detected and suppressed errors, rerun with: -s
==52659== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

```

I manually tested `SDL_DBus_Quit`, and it didn’t show any issues during cleanup.

```auto
void SDL_DBus_Quit(void)
{
    if (!SDL_ShouldQuit(&dbus_init)) {
        return;
    }

    if (inhibit_handle) {
        SDL_Log("Freeing inhibit_handle: %s", inhibit_handle);
        if (!SDL_DBus_CallVoidMethod("org.freedesktop.portal.Desktop", inhibit_handle, "org.freedesktop.portal.Request", "Close", DBUS_TYPE_INVALID)) {
            SDL_Log("Failed to close inhibit handle for: %s", inhibit_handle);
        } else {
            SDL_Log("Successfully closed inhibit handle: %s", inhibit_handle);
        }
        SDL_free(inhibit_handle);
        inhibit_handle = NULL;
    }

    if (dbus.system_conn) {
        SDL_Log("Closing system connection: %p", dbus.system_conn);
        if (!dbus.connection_get_is_connected(dbus.system_conn)) {
            SDL_Log("System connection is already closed");
        } else {
            dbus.connection_close(dbus.system_conn); 
            dbus.connection_unref(dbus.system_conn); 
            SDL_Log("System connection successfully closed");
        }
        dbus.system_conn = NULL;
    }

    if (dbus.session_conn) {
        SDL_Log("Closing session connection: %p", dbus.session_conn);
        if (!dbus.connection_get_is_connected(dbus.session_conn)) {
            SDL_Log("Session connection is already closed");
        } else {
            dbus.connection_close(dbus.session_conn);
            dbus.connection_unref(dbus.session_conn);
            SDL_Log("Session connection successfully closed");
        }
        dbus.session_conn = NULL;
    }

    if (SDL_GetHintBoolean(SDL_HINT_SHUTDOWN_DBUS_ON_QUIT, false) && dbus.shutdown) {
        SDL_Log("Calling dbus.shutdown");
        dbus.shutdown();
        SDL_Log("DBus shutdown completed");
    }

    SDL_zero(dbus);

    if (dbus_handle) {
        SDL_Log("Unloading DBus library: %p", dbus_handle);
        SDL_UnloadObject(dbus_handle);
        dbus_handle = NULL;
        SDL_Log("DBus library unloaded");
    }

    SDL_SetInitialized(&dbus_init, false);
}

```

Despite this, the memory leak indicated by Valgrind still seems to occur during `SDL_DBus_Init`. Could this be related to allocations not covered in `SDL_DBus_Quit`?
