2011-08-30 60 views
2

每當我有一個函數,它接受一個C字符串,並希望它的值存儲鏈表裏面,我應該做這樣的...我的函數應該拷貝`char *` - 參數嗎?

void add(char* str) 
{ 
    node *n = malloc(sizeof(node)); 
    n->value = str; 
} 

或者說...

void add(char* str) 
{ 
    node *n = malloc(sizeof(node)); 
    char* copy = malloc(strlen(str)+1); 
    strcpy(copy, str); 
    n->value = copy; 
} 

在此先感謝。

+2

無關,但我假設你的意思是'malloc(sizeof(* n))''malloc(strlen(str) +1)'。 –

+0

@rob不同意第一個。糾正了第二個。謝謝。 – imacake

+1

您正在分配一個大小爲「節點*」而不是「節點」的指針。你也可以使用'strdup'來複制字符串,而不是'malloc' +'strcpy' – Hasturkun

回答

7

它真的取決於來自哪裏的論據,以及你對這些論點的意圖是什麼。

如果您知道作爲參數傳遞的字符串在鏈表的整個生命週期中始終可用,並且它們未被修改或釋放,或者沒有會影響鏈接的任何副作用的函數-list,那麼你可以簡單地複製指針而不費心去複製整個字符串。

如果上述任何一個不正確(我的意思是,如果您不知道上述答案之一),那麼複製整個字符串會更安全。

一些具體的例子:

  • 你正在開發的小型應用程序讀取CSV文件,存儲在分類鏈接列表中的值,然後把一個值返回到一個XML文件中:你有控制字符串的整個生命週期,您不必複製它們。

  • 你正在寫一個鏈接列表庫,可能在網上發佈,可能被數百人在所有類型的領域中活躍使用:你不知道將傳遞給你的庫的內容是什麼,知道庫用戶在操作鏈表之前是否會釋放字符串,然後複製整個字符串。

也注意到,這種設計決定的是更好地記錄某個地方:它是作爲一個開發者,以明確你的函數將指針存儲而不復制字符串,或者你會複製字符串和你的責任將需要另一個函數調用來釋放內存。 (這被稱爲design by contract:你使用你的函數和函數本身建立了代碼之間的契約,你最好尊重它,否則你將會遇到問題,以數據損壞或軟件崩潰的形式出現)。一種可能的方式可以讓您的意圖清晰明瞭,就是使用適當放置的const關鍵字。

+0

+1按合同設計。這確實是關鍵 - 你必須建立,遵循和記錄你要遵循的約定。如果我能指出另一個+1,指出理想的約定會根據您的應用而變化。 –

1

str的所有權是什麼?這是一個malloc編輯緩衝區與動態數據?在程序中調用add是否將指向鏈接列表的所有權?

沒有正確答案,因爲它取決於str的使用方式。

0

我寧願更喜歡第二個選項,因爲: - - 即使它工作,代碼也不可維護 - 如果原始字符串str被刪除,第一個選項會留下懸空指針的較大間隔。沒有辦法確定程序中實際製作了多少個指針str。 - 任何內存工具也會抱怨,導致輸出變臃腫,因此難以調試任何實際的內存問題

+0

很抱歉,您現在支持#1或#2 ...:s? – imacake