为什么 valgrind 说基本 SDL 程序正在泄漏内存?

发布于 2024-08-16 21:01:30 字数 4860 浏览 7 评论 0原文

这是 SDL 程序:

#include <SDL/SDL.h>

int main(int argc, char** argv){


  SDL_Init(SDL_INIT_VIDEO);
  SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE);
  SDL_Quit();
  return 0;

}

使用以下命令编译:

g++ -o test test.cpp -lSDL

这是 valgrind 的输出:

christian@christian-laptop:~/cpp/tetris$ valgrind --leak-check=full ./test
==3271== Memcheck, a memory error detector
==3271== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==3271== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for copyright info
==3271== Command: ./test
==3271== 
==3271== 
==3271== HEAP SUMMARY:
==3271==     in use at exit: 91,097 bytes in 1,258 blocks
==3271==   total heap usage: 14,250 allocs, 12,992 frees, 2,615,177 bytes allocated
==3271== 
==3271== 10 bytes in 2 blocks are definitely lost in loss record 8 of 134
==3271==    at 0x4024C1C: malloc (vg_replace_malloc.c:195)
==3271==    by 0x4946F04: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x4945DA1: _XimEncodeLocalICAttr (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x4947195: _XimSetICValueData (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x493FDF1: _XimLocalCreateIC (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x4922478: XCreateIC (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x407AA64: ??? (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x407BCBB: ??? (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x4069C2A: SDL_VideoInit (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x403F9D3: SDL_InitSubSystem (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x403FA36: SDL_Init (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x8048658: main (in /home/christian/cpp/tetris/test)
==3271== 
==3271== 12 bytes in 1 blocks are definitely lost in loss record 12 of 134
==3271==    at 0x4024C1C: malloc (vg_replace_malloc.c:195)
==3271==    by 0x4A3DA8D: ???
==3271==    by 0x4A3D48C: ???
==3271==    by 0x4A3D5A4: ???
==3271==    by 0x4A3DD26: ???
==3271==    by 0x4A38BC5: ???
==3271==    by 0x4A38FCD: ???
==3271==    by 0x40717DD: ??? (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x407BDCA: ??? (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x4069C2A: SDL_VideoInit (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x403F9D3: SDL_InitSubSystem (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x403FA36: SDL_Init (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271== 
==3271== 112 (8 direct, 104 indirect) bytes in 1 blocks are definitely lost in loss record 102 of 134
==3271==    at 0x4024D12: realloc (vg_replace_malloc.c:476)
==3271==    by 0x492847E: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x492976D: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x492AA41: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x492B1A4: _XlcCreateLC (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x494B4FA: _XlcDefaultLoader (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x4933153: _XOpenLC (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x49332C2: _XlcCurrentLC (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x4933761: XSetLocaleModifiers (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x407161D: ??? (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x407AD8F: ??? (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x407BCBB: ??? (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271== 
==3271== 112 (8 direct, 104 indirect) bytes in 1 blocks are definitely lost in loss record 103 of 134
==3271==    at 0x4024D12: realloc (vg_replace_malloc.c:476)
==3271==    by 0x492847E: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x492976D: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x492AA41: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x492B1A4: _XlcCreateLC (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x494B4FA: _XlcDefaultLoader (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x4933153: _XOpenLC (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x493327D: _XrmInitParseInfo (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x4918F20: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x491AF37: XrmGetStringDatabase (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x48F8459: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x48F864E: XGetDefault (in /usr/lib/libX11.so.6.2.0)
==3271== 
==3271== LEAK SUMMARY:
==3271==    definitely lost: 38 bytes in 5 blocks
==3271==    indirectly lost: 208 bytes in 8 blocks
==3271==      possibly lost: 0 bytes in 0 blocks
==3271==    still reachable: 90,851 bytes in 1,245 blocks
==3271==         suppressed: 0 bytes in 0 blocks
==3271== Reachable blocks (those to which a pointer was found) are not shown.
==3271== To see them, rerun with: --leak-check=full --show-reachable=yes
==3271== 
==3271== For counts of detected and suppressed errors, rerun with: -v
==3271== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 93 from 14)

为什么这个基本的 SDL 程序会泄漏内存?

Here is the SDL program:

#include <SDL/SDL.h>

int main(int argc, char** argv){


  SDL_Init(SDL_INIT_VIDEO);
  SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE);
  SDL_Quit();
  return 0;

}

Compiled with the command:

g++ -o test test.cpp -lSDL

And here is the output of valgrind:

christian@christian-laptop:~/cpp/tetris$ valgrind --leak-check=full ./test
==3271== Memcheck, a memory error detector
==3271== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==3271== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for copyright info
==3271== Command: ./test
==3271== 
==3271== 
==3271== HEAP SUMMARY:
==3271==     in use at exit: 91,097 bytes in 1,258 blocks
==3271==   total heap usage: 14,250 allocs, 12,992 frees, 2,615,177 bytes allocated
==3271== 
==3271== 10 bytes in 2 blocks are definitely lost in loss record 8 of 134
==3271==    at 0x4024C1C: malloc (vg_replace_malloc.c:195)
==3271==    by 0x4946F04: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x4945DA1: _XimEncodeLocalICAttr (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x4947195: _XimSetICValueData (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x493FDF1: _XimLocalCreateIC (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x4922478: XCreateIC (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x407AA64: ??? (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x407BCBB: ??? (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x4069C2A: SDL_VideoInit (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x403F9D3: SDL_InitSubSystem (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x403FA36: SDL_Init (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x8048658: main (in /home/christian/cpp/tetris/test)
==3271== 
==3271== 12 bytes in 1 blocks are definitely lost in loss record 12 of 134
==3271==    at 0x4024C1C: malloc (vg_replace_malloc.c:195)
==3271==    by 0x4A3DA8D: ???
==3271==    by 0x4A3D48C: ???
==3271==    by 0x4A3D5A4: ???
==3271==    by 0x4A3DD26: ???
==3271==    by 0x4A38BC5: ???
==3271==    by 0x4A38FCD: ???
==3271==    by 0x40717DD: ??? (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x407BDCA: ??? (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x4069C2A: SDL_VideoInit (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x403F9D3: SDL_InitSubSystem (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x403FA36: SDL_Init (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271== 
==3271== 112 (8 direct, 104 indirect) bytes in 1 blocks are definitely lost in loss record 102 of 134
==3271==    at 0x4024D12: realloc (vg_replace_malloc.c:476)
==3271==    by 0x492847E: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x492976D: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x492AA41: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x492B1A4: _XlcCreateLC (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x494B4FA: _XlcDefaultLoader (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x4933153: _XOpenLC (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x49332C2: _XlcCurrentLC (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x4933761: XSetLocaleModifiers (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x407161D: ??? (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x407AD8F: ??? (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271==    by 0x407BCBB: ??? (in /usr/lib/libSDL-1.2.so.0.11.2)
==3271== 
==3271== 112 (8 direct, 104 indirect) bytes in 1 blocks are definitely lost in loss record 103 of 134
==3271==    at 0x4024D12: realloc (vg_replace_malloc.c:476)
==3271==    by 0x492847E: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x492976D: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x492AA41: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x492B1A4: _XlcCreateLC (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x494B4FA: _XlcDefaultLoader (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x4933153: _XOpenLC (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x493327D: _XrmInitParseInfo (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x4918F20: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x491AF37: XrmGetStringDatabase (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x48F8459: ??? (in /usr/lib/libX11.so.6.2.0)
==3271==    by 0x48F864E: XGetDefault (in /usr/lib/libX11.so.6.2.0)
==3271== 
==3271== LEAK SUMMARY:
==3271==    definitely lost: 38 bytes in 5 blocks
==3271==    indirectly lost: 208 bytes in 8 blocks
==3271==      possibly lost: 0 bytes in 0 blocks
==3271==    still reachable: 90,851 bytes in 1,245 blocks
==3271==         suppressed: 0 bytes in 0 blocks
==3271== Reachable blocks (those to which a pointer was found) are not shown.
==3271== To see them, rerun with: --leak-check=full --show-reachable=yes
==3271== 
==3271== For counts of detected and suppressed errors, rerun with: -v
==3271== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 93 from 14)

Why is this basic SDL program leaking memory?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

合久必婚 2024-08-23 21:01:30

即使对于没有完整 SDL 的基本 OpenGL“hello world”程序,Valgrind 也会在 OpenGL 库深处向我发出类似的警告。这很奇怪,但我假设

  • 库实现者知道他们在做什么(可能预先分配了一些他们从不费心释放的小型静态缓冲区),
  • 即使他们不这样做,这也是一次性泄漏,将由当程序终止时操作系统,

并且没有因此而失去太多睡眠。

Even for basic OpenGL "hello world" program without the full SDL, Valgrind gives me similar warnings deep inside the OpenGL libraries. It's peculiar, but I've assumed

  • The library implementors know what they're doing (probably preallocating some small static buffers they never bother to free),
  • Even if they don't, it's a one-time leak that'll be reclaimed by the OS when the program terminates,

and haven't lost much sleep over it.

初吻给了烟 2024-08-23 21:01:30

这对于图形 API 库(OpenGL、Vulkan 等)和窗口 API(X11、SDL 等)来说是正常的。最好的选择是使用 valgrind 抑制文件来忽略这些错误。

以下是如何使用 Linux、SDL 和 Linux 来实现这一点。 OpenGL:

假设您正在调试的程序名为“prog.out”(请记住将 prog.out 替换为程序的实际名称),

您可以像这样导出抑制信息:

valgrind --leak-check=full --show-reachable=yes --show-leak-kinds=all --error-limit=no --gen-suppressions=all --log-file=supdata.log ./prog.out

您现在可以从“supdata”中提取抑制信息.log' 使用脚本或手动。您可以使用通配符(“*”、“...”)使抑制更加通用(从而不必在每次更新代码时都更新抑制文件)。

之后,每当您调试程序时,您都会从现在开始包含抑制文件。例如,我在“linux_sdl_gl.sup”下面制作了抑制文件。当我在 Linux 上使用 SDL 和 OpenGL 进行开发时,它非常适合我。它忽略所有 OpenGL、SDL 和 X11 内置错误,以便我可以轻松找到我创建的错误。请随意在您的开发中使用它。

当我调试代码时,我使用以下对 valgrind 的调用。这使我能够找到我的抑制文件可能遗漏的任何新系统错误。

valgrind --gen-suppressions=all --suppressions=./linux_sdl_gl.sup --leak-check=full --show-leak-kinds=all ./prog.out

文件:linux_sdl_gl.sup

# Copyright (c) <'2019'> <'Alrick Grandison'>

# This software is provided 'as-is', without any express or implied
# warranty. In no event will the authors be held liable for any damages
# arising from the use of this software.

# Permission is granted to anyone to use this software for any purpose,
# including commercial applications, and to alter it and redistribute it
# freely, subject to the following restrictions:

# 1. The origin of this software must not be misrepresented; you must not
#    claim that you wrote the original software. If you use this software
#    in a product, an acknowledgment in the product documentation would be
#    appreciated but is not required.
# 2. Altered source versions must be plainly marked as such, and must not be
#    misrepresented as being the original software.
# 3. This notice may not be removed or altered from any source distribution.

{
   opengl_memcpy_addr8
   Memcheck:Addr8
   fun:memcpy@GLIBC*
   obj:/usr/lib/x86_64-linux-gnu/dri/*_dri.so
   ...
}

{
   opengl_memcpy_addr1
   Memcheck:Addr1
   fun:memcpy@GLIBC*
   obj:/usr/lib/x86_64-linux-gnu/dri/*_dri.so
   ...
}

{
   opengl_memset_addr8
   Memcheck:Addr8
   fun:memset
   obj:/usr/lib/x86_64-linux-gnu/dri/*_dri.so
   ...
}

{
   sdl_leak_reachable
   Memcheck:Leak
   match-leak-kinds: reachable
   ...
   fun:SDL_Init_REAL
   ...
}

{
   x11_leak_reachable
   Memcheck:Leak
   match-leak-kinds: reachable
   ...
   obj:/usr/lib/x86_64-linux-gnu/libX11.so.*
   ...
}

{
   sdl_leak_indirect
   Memcheck:Leak
   match-leak-kinds: indirect
   ...
   fun:SDL_Init_REAL
   ...
}

{
  sdl_leak_definite
   Memcheck:Leak
   match-leak-kinds: definite
   ...
   fun:SDL_Init_REAL
   ...
}

# OpenGL Calls DL under the Hood - Taken straight out of Valgrind --gen-suppressions
# Could overlap with non-graphics DL api calls
# But, If you are not using DL directly, then don't worry about this
{
   dl_leak_reachable
   Memcheck:Leak
   match-leak-kinds: reachable
   ...
   fun:dlopen@@GLIBC*
   ...
}

# Same as above but more generic
# Could overlap with non-graphics DL api calls
# But, If you are not using DL directly, then don't worry about this
{
   dl_leak_reachable
   Memcheck:Leak
   match-leak-kinds: reachable
   ...
   fun:_dl_*
   ...
}

{
   x11_leak_indirect
   Memcheck:Leak
   match-leak-kinds: indirect
   ...
   obj:/usr/lib/x86_64-linux-gnu/libX11.so.*
   ...
}

{
   x11_leak_definite
   Memcheck:Leak
   match-leak-kinds: definite
   ...
   obj:/usr/lib/x86_64-linux-gnu/libX11.so.*
   ...
}

{
   x11_leak_possible
   Memcheck:Leak
   match-leak-kinds: possible
   ...
   obj:/usr/lib/x86_64-linux-gnu/libX11.so.*
   ...
}

{
   opengl_leak_reachable
   Memcheck:Leak
   match-leak-kinds: reachable
   ...
   obj:/usr/lib/x86_64-linux-gnu/libGLX.so.*
   ...
}

github:valgrind 抑制代码

This is normal for the graphics API library (OpenGL, Vulkan, etc) and windowing API (X11, SDL, etc). This best option is to use valgrind suppression files to ignore these errors.

Here is how to do it with Linux, SDL & OpenGL:

Let's say the program you are debugging is called 'prog.out' (remember to replace prog.out with the actual name of your program),

You can export suppression info like this:

valgrind --leak-check=full --show-reachable=yes --show-leak-kinds=all --error-limit=no --gen-suppressions=all --log-file=supdata.log ./prog.out

You can now extract the suppression info from 'supdata.log' using a script or manually. You can use wildcards ('*', '...') to make suppressions more generic (thereby not having to update the suppression file each time you update your code).

After that, whenever you debug your program you would include the suppression file from now on. For example, I made the suppression file below 'linux_sdl_gl.sup'. It works well for me when developing using SDL and OpenGL on Linux. It ignores all of OpenGL, SDL and X11 built in errors so that I can easily find errors I create. Feel free to use it in your development.

When I debug my code I use the following call to valgrind. This allows me to find any new system bugs that my suppression file may have missed.

valgrind --gen-suppressions=all --suppressions=./linux_sdl_gl.sup --leak-check=full --show-leak-kinds=all ./prog.out

file: linux_sdl_gl.sup

# Copyright (c) <'2019'> <'Alrick Grandison'>

# This software is provided 'as-is', without any express or implied
# warranty. In no event will the authors be held liable for any damages
# arising from the use of this software.

# Permission is granted to anyone to use this software for any purpose,
# including commercial applications, and to alter it and redistribute it
# freely, subject to the following restrictions:

# 1. The origin of this software must not be misrepresented; you must not
#    claim that you wrote the original software. If you use this software
#    in a product, an acknowledgment in the product documentation would be
#    appreciated but is not required.
# 2. Altered source versions must be plainly marked as such, and must not be
#    misrepresented as being the original software.
# 3. This notice may not be removed or altered from any source distribution.

{
   opengl_memcpy_addr8
   Memcheck:Addr8
   fun:memcpy@GLIBC*
   obj:/usr/lib/x86_64-linux-gnu/dri/*_dri.so
   ...
}

{
   opengl_memcpy_addr1
   Memcheck:Addr1
   fun:memcpy@GLIBC*
   obj:/usr/lib/x86_64-linux-gnu/dri/*_dri.so
   ...
}

{
   opengl_memset_addr8
   Memcheck:Addr8
   fun:memset
   obj:/usr/lib/x86_64-linux-gnu/dri/*_dri.so
   ...
}

{
   sdl_leak_reachable
   Memcheck:Leak
   match-leak-kinds: reachable
   ...
   fun:SDL_Init_REAL
   ...
}

{
   x11_leak_reachable
   Memcheck:Leak
   match-leak-kinds: reachable
   ...
   obj:/usr/lib/x86_64-linux-gnu/libX11.so.*
   ...
}

{
   sdl_leak_indirect
   Memcheck:Leak
   match-leak-kinds: indirect
   ...
   fun:SDL_Init_REAL
   ...
}

{
  sdl_leak_definite
   Memcheck:Leak
   match-leak-kinds: definite
   ...
   fun:SDL_Init_REAL
   ...
}

# OpenGL Calls DL under the Hood - Taken straight out of Valgrind --gen-suppressions
# Could overlap with non-graphics DL api calls
# But, If you are not using DL directly, then don't worry about this
{
   dl_leak_reachable
   Memcheck:Leak
   match-leak-kinds: reachable
   ...
   fun:dlopen@@GLIBC*
   ...
}

# Same as above but more generic
# Could overlap with non-graphics DL api calls
# But, If you are not using DL directly, then don't worry about this
{
   dl_leak_reachable
   Memcheck:Leak
   match-leak-kinds: reachable
   ...
   fun:_dl_*
   ...
}

{
   x11_leak_indirect
   Memcheck:Leak
   match-leak-kinds: indirect
   ...
   obj:/usr/lib/x86_64-linux-gnu/libX11.so.*
   ...
}

{
   x11_leak_definite
   Memcheck:Leak
   match-leak-kinds: definite
   ...
   obj:/usr/lib/x86_64-linux-gnu/libX11.so.*
   ...
}

{
   x11_leak_possible
   Memcheck:Leak
   match-leak-kinds: possible
   ...
   obj:/usr/lib/x86_64-linux-gnu/libX11.so.*
   ...
}

{
   opengl_leak_reachable
   Memcheck:Leak
   match-leak-kinds: reachable
   ...
   obj:/usr/lib/x86_64-linux-gnu/libGLX.so.*
   ...
}

github: valgrind supression code

廻憶裏菂餘溫 2024-08-23 21:01:30

您加载的每个 SDL_Surface 都应该在调用 SDL_Quit() 之前释放。

为此,只需使用 SDL_FreeSurface(surfaceName) 来释放在内存上分配的表面。

Every SDL_Surface you load should be freed before the call of SDL_Quit().

To do this, just use SDL_FreeSurface(surfaceName) to free up the surface that you allocated on memory.

生寂 2024-08-23 21:01:30

SDL 的 SDL_TLSCleanupSDL_TLSData 肯定存在内存泄漏问题。

事实上,SDL_TLSCleanup 永远不会被线程调用。

SDL definitely has a memory leak issue with SDL_TLSCleanup and SDL_TLSData.

In fact, SDL_TLSCleanup is never called for the main thread.

随遇而安 2024-08-23 21:01:30

单例几乎总是标准实现的“泄漏”。不过,这通常是可以的,因为通常您不想卸载执行诸如打印到控制台之类的操作的能力。

Singletons are pretty much always a 'leak' with standard implementations. That is usually ok, though, since normally it's not like you want to unload your ability to do things like print to the console.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文