我试着用C编写一个游戏,每次刷新diplay时,使用SDL_ttf来显示得分。代码如下:

SDL_Surface *score = NULL;

TTF_Font *font;
SDL_Color color = { 255, 255, 255 };
font = TTF_OpenFont( "/home/sophie/Bureau/snake/data/ubuntu.ttf", 28 );
if (font == NULL) {
    printf("%s\n", TTF_GetError());
}

score = TTF_RenderText_Solid( font, "score to display", color );

SDL_BlitSurface( score, NULL, screen, NULL );
SDL_Flip(screen);

当我启动游戏时,一切正常,但过了一段时间,游戏崩溃,我得到以下错误:
Couldn't open /home/sophie/Bureau/snake/data/ubuntu.ttf
libgcc_s.so.1 must be installed for pthread_cancel to work
Abandon (core dumped)

我试过不同的字体,但还是有这个问题。
然后我在游戏的主循环中使用了一个计数器,发现游戏总是在第1008次之后崩溃,不管我希望它以何种速度工作(在snake中,当你得分时,一切都会变得更快)。
我不知道问题从何而来,也不知道错误消息的确切含义。
如果你有什么想法,或者我的问题表述不好,请告诉我。我在几家论坛上都找不到与我的案子相符的东西,我现在可以求助了!
提前谢谢

最佳答案

每次执行此功能时,您似乎都在重复打开字体:

font = TTF_OpenFont( "/home/sophie/Bureau/snake/data/ubuntu.ttf", 28 );

虽然它可能不像Jongware所怀疑的那样在主游戏循环中,但您提到,通过此代码路径执行1008次之后,代码崩溃。
正在发生的是一些资源被泄露。要么需要通过调用TTF_CloseFont()释放资源,要么(更有效)在第一次打开句柄后按住它并每次重新使用它。对字体使用static声明并初始化为NULL
static TTF_Font *font = NULL;

然后,如果还没有打开,请打开它:
if (!font) {
    font = TTF_OpenFont( "/home/sophie/Bureau/snake/data/ubuntu.ttf", 28 );
}

这将在第一次初始化font,而随后的代码迭代不会不必要地重新执行进程并泄漏资源。
您曾提到,通过此函数,代码在1008次之后崩溃。差不多是1024个。作为内存服务,Linux对每个进程有1024个文件句柄的限制(这在内核中可能是可调的,但我以前在调试资源泄漏时遇到过这个限制)。您的进程可能打开了16个其他文件句柄,然后每次调用TTF_OpenFont都会泄漏1个进程。一旦你超过1024,砰。
通过检查<pid>中文件描述符的数量,可以检查特定进程(/proc/<pid>/fd/)的打开文件句柄的数量。

10-08 03:48