2012-09-04 48 views
2

縱觀我從前輩繼承的程序,有以下格式的功能:多次調用的strdup()使用相同的左值

somefunc(some_type some_parameter, char ** msg) 

換句話說,最後一個參數是一個char **,這是用於返回消息。 即:somefunc()將「更改」msg。 在某些情況下,有問題的變化的形式爲:

sprintf(txt,"some text. Not fixed but with a format and variables etc"); 
    LogWar("%s",txt); //call to some logging function that uses txt 
    *msg = strdup(txt); 

我知道,每次調用strdup()應該有一個相關的呼叫free()釋放它分配的內存。

由於該內存用於返回某些內容,因此顯然不應在somefunc()的末尾釋放。

但那麼在哪裏?

如果將somefunc()相同的 msg多次調用,那麼該指針將四處移動,我假設。所以以前的通話分配的空間會丟失,對吧?

程序結束前的某處我當然應該free(*msg)。 (在這種情況下*msg是用作調用somefunc()參數的版本。) 但我認爲,呼叫只會釋放最後分配的內存,而不是存儲在早期呼叫分配給somefunc(),對不對?

所以,我在說somefunc()應該是這樣的更正:那麼有free()strdup()

sprintf(txt,"some text. Not fixed like here, but actually with variables etc"); 
    LogWar("%s",txt); //call to some logging function that uses txt 
    free(*msg); //free up the memory that was previously assigned to msg, since we will be re-allocating it immediatly hereafter 
    *msg = strdup(txt); 

我正確嗎?

+2

通常當你傳遞類似於這個函數的指針地址時,通常調用者有責任釋放返回的任何分配的資源。作爲一個經驗法則,當你不再需要內存時,就可以釋放它。 –

回答

1

是的,你是對的。在覆蓋它之前,從strdup()返回的任何舊指針必須爲free()d,否則會泄漏內存。

我敢肯定,你在哪裏是簡單的清晰度,但我當然會投給這樣的事情:

const char * set_error(char **msg, const char *text) 
{ 
    free(*msg); 
    *msg = strdup(text); 
} 

然後:

LogWar("%s",txt); //call to some logging function that uses txt 
set_error(msg, txt); 

看我怎麼用封裝讓這個非常重要的序列更加明確,甚至命名?

+0

或者,您可以考慮靜態分配'msg'。在這種情況下,即使在內存不足的情況下,您也可以顯示日誌消息。 – user1202136

+0

所以我用你的'set_error(msg,txt)'替換了所有'* msg = strdup(txt);'。這應該很容易做到。謝謝! – JochenVdB

相關問題