2014-02-07 146 views
1

我試圖在C中使用SDL_ttf在每次刷新頁面時顯示比分。代碼如下:TTF_OpenFont在第N次嘗試時失敗

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次後總是崩潰,無論我希望它的工作速度如何(在蛇中,當你得分時,一切都會更快)。

我不知道問題來自何處,也不知道錯誤消息的含義。

請告訴我,如果您有任何想法,或者如果我的問題制定得不好。我看了幾個論壇,沒有發現與我的案例相對應的內容,我現在可以使用任何幫助!

在此先感謝

+0

從你的描述中,我得到了你在做主遊戲循環中的'TTF_OpenFont'的印象。那是對的嗎? – usr2564301

+0

不,實際上,此段位於由主循環中的另一個函數調用的函數內。我認爲這將是太複雜,不能給真正的代碼,因爲錯誤信息表明錯誤在這裏......我錯了嗎? – Zeenoth

回答

0

它看起來像你每次經過這個函數時反覆打開字體:

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,繁榮

您可以通過檢查/proc/<pid>/fd/中的文件描述符的數量來檢查特定進程的打開文件句柄的數量(<pid>)。

+0

我從來沒有聽說過靜態聲明,我試過你說的。看來問題正是你所說的,現在我的程序運行得很完美。非常感謝你 ! – Zeenoth

+0

請務必閱讀更多靜態聲明。 「靜態」意味着取決於上下文的幾個不同的事情。另外,根據我的經驗,訪問者喜歡將這些不同的靜態使用上下文用於C相關工作的面試問題。 :-) –

+0

好的,我會讀更多關於它的^^另外,我一直在研究/ proc//fd /並使用ll來查看裏面的內容,發現有兩個套接字。我沒有做任何與網絡有關的事情,這兩個元素是如何出現的? – Zeenoth

相關問題