我需要一個函數來記錄一些信息,如:ALLOCA VS固定緩衝格式化字符串
void log(char* format, ...);
對於形式的緩衝方法有幾種:
有一個固定大小的緩衝區。這不會導致溢出,但可能會截斷消息。
void log1(char* format, ...)
{
char buffer[BUFFER_SIZE];
va_list args;
va_start(args, format);
vsnprintf(buffer, BUFFER_SIZE, format, args);
va_end(args);
}
有一個可變長度緩衝區。分配堆棧上的內存時可能會導致溢出。當內存分配在堆上時,我不會考慮這種情況。這是一個設計限制。
void log2(char* format, ...)
{
va_list args;
va_start(args, format);
int length = vsnprintf(NULL, 0, format, args);
char* buffer = (char*)alloca(length + 1);
vsnprintf(buffer, length+1, format, args);
va_end(args);
}
該函數將從多個線程中調用,因此保持一個通用的全局緩衝區不是一個選項(鎖定太多)。由於一些舊的編譯器/可執行格式限制,TLS也不是一種選擇。
我應該選擇哪個版本?使用第一種或第二種方法是否還有其他明顯的優勢/劣勢?
第一個解決方案稍快,因爲vsnprintf不會被調用兩次。如果你認爲一行日誌永遠不會太長,那麼alloca不太可能觸發一個stackoverflow。我會選擇第一個解決方案,併爲BUFFER_SIZE(1000到2000個字符)選擇一個合理的大小。 –
建議過長線本身是一個不應該傳播的錯誤。因此,我會選擇一個慷慨的固定大小的緩衝區。 – chux