[英]C programming, char array memory allocation issue
我正在開發一個小的C庫來教視頻游戲編程,並且我創建了一個簡單的函數來在屏幕上繪制格式化的文本(即得分,生命)。 該函數是:
const char *FormatText(const char *text, ...)
{
int length = strlen(text);
char *buffer = malloc(length + 20);
va_list args;
va_start(args, text);
vsprintf(buffer, text, args);
va_end(args);
return buffer;
}
此功能在游戲主循環的“繪制”部分中使用,如下所示:
DrawText(FormatText("%02i", score), 10, 10, 40, BLACK);
DrawText()函數中的其他參數僅表示屏幕坐標X,Y,字體大小和顏色。
我每秒調用此函數約60次(甚至更多),因此,如果我是對的,我將在每次調用時分配新的內存...而且我永遠不會釋放該內存!
如何解決此問題以繼續使用我的函數?
我的第一個想法是在我的庫上創建一個全局char * buffer,在初始化時分配它,然后一直重復使用...但是我不確定這是否是最好的主意,我嘗試避免使用過多的globals。
非常感謝您的回答!
再次感謝大家的回答。
最后,我解決此問題的方法是使用:
const char *FormatText(const char *text, ...)
{
static char buffer[MAX_FORMATTEXT_LENGTH];
va_list args;
va_start(args, text);
vsprintf(buffer, text, args);
va_end(args);
return buffer;
}
可能不是最好的解決方案,但我認為這對於lib用戶是最好的,而不必擔心內存管理。
這是一個簡單的用法示例:
#include "raylib.h"
int main()
{
int score = 100020;
int hiscore = 200450;
int lives = 5;
InitWindow(800, 450, "testing FormatText()");
SetTargetFPS(60);
while (!WindowShouldClose()) // Detect window close button or ESC key
{
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText(FormatText("Score: %08i", score), 80, 80, 20, RED);
DrawText(FormatText("HiScore: %08i", hiscore), 80, 120, 20, GREEN);
DrawText(FormatText("Lives: %02i", lives), 80, 160, 40, BLUE);
DrawText(FormatText("Elapsed Time: %02.02f ms", GetFrameTime()*1000), 80, 220, 20, BLACK);
EndDrawing();
}
CloseWindow();
return 0;
}
結果是:
我將管理內存的責任交給了父函數。 它會根據需要分配和釋放,而不是FormatText()
本身
// somefunction
char *buffer;
buffer = malloc(<somesize>);
if (buffer) {
FormatText(buffer, "%02i", ...);
free(buffer);
}
您的函數幾乎已經存在於某些Libc中,例如GNU libc ,它稱為asprintf(3) 。 調用者應free
malloc
分配的緩沖區。
您可以將其用作:
char* msg=NULL;
DrawText((msg=FormatText("%02i", score)), 10, 10, 40, BLACK);
free (msg);
或者,如果使用asprintf
,則使用逗號運算符 ,
char* msg=NULL;
DrawText((asprintf(&msg,"%02i",score),msg), 10, 10, 40, BLACK);
free (msg);
最后,如果您因應該free
調用而煩惱,則可以決定整個程序都使用Boehm垃圾收集器 (因此,您將調用GC_MALLOC
而不用擔心GC_FREE
)。 然后,您將定義
char* GC_sprintf(const char*fmt, ...) {
char buf[128];
va_list ap;
va_start (ap, fmt);
int sz = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end (ap);
if (sz < sizeof(buf)) return GC_strdup (buf);
char* gcbuf = GC_MALLOC_ATOMIC (sz+1);
memset (gcbuf, 0, sizeof (gcbuf));
va_start (ap, fmt);
vsnprintf(gcbuf, sz, fmt, ap);
va_end (ap);
return gcbuf;
}
然后簡單地打電話
DrawText(GC_sprintf("%02i",score), 10, 10, 40, BLACK);
順便說一句,由於"%02i"
格式會產生一個短字符串,因此您可以使用
char locbuf[8];
snprintf (locbuf, sizeof(locbuf), "%02i", score);
DrawText(locbuf, 10, 10, 40, BLACK);
您甚至可以考慮定義可變參數的DrawText_printf
並調用
DrawText_printf(10, 10, 40, BLACK, "%02i", score);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.