2015-09-04 97 views
3

我有一個宏定義如下。此外,在我的計劃,我需要在2種樣式打印出錯誤消息:什麼時候釋放字符串指針?

  1. PRINT_ERR("This is Error!");
  2. 使用asprint構建日誌字符串,然後把它打印出來:
char *log = NULL; 
int age = 0; 
asprintf(&log, "error: %s on: %d", "Name", age); 
PRINT_ERR(log); 

在低於宏定義的情況下,風格#1會拋出異常。 因此,在宏定義中,我如何弄清楚在哪種情況下,我需要釋放字符串「y」?

#define PRINT_LOG(x, y) { \ 
    printf ("%s: %s\n", x, y);\ 
    free(y);\ //how do I know "y" is a pointer, or a string like this "string"? 
} 

#define PRINT_ERR(y) { PRINT_LOG ("ERR ", y) } 
+4

#1無法釋放反正,因爲該字符串未分配動態。它被編譯到可執行文件中,並且總是在內存中。 –

+0

所以你真的想打印「錯誤:錯誤:名稱:0」? (看起來很尷尬......) – crashmstr

+3

「我怎麼知道」y「是一個指針,或像這樣的字符串」string「」 - 你不知道。你*不需要知道。*設計你的程序的方式,你不需要知道你的字符串是字面的還是動態分配的。 –

回答

3

難道你不能使用兩個不同的宏 - 沿着下面的幾行?

#define PRINT_ERR(y) .... 

#define PRINT_ERR_FREE(y) \ 
    do { \ 
     PRINT_ERR(y); \ 
     free(y);\ 
    } while (0); 
2

您的宏/功能/不管不能字符串和動態分配的字符串區分,因此,你不能總是free()字符串參數,因爲字面字符串不能free「d。

簡單的解決辦法是寫一個可變參數函數(或可變參數宏,如果你還是喜歡):

void LOG(const char* format, ...) 
{ 
    char *str = NULL; 
    va_list argptr; 
    va_start(argptr, format); 
    int ret = vasprintf(&str, format, argptr); 
    if (ret == -1) { 
     fprintf(stderr, "Failed to allocate memory\n"); 
     exit(EXIT_FAILURE); 
    } 
    va_end(argptr); 
    PRINT_ERR(str); 
    free(str); 
}