2011-05-05 153 views
8

編寫在C中返回字符串的方法時什麼被認爲是更好的做法?處理返回的C字符串

傳遞一個緩衝器和大小:

void example_m_a(type_a a,char * buff,size_t buff_size) 

或製備和返回適當大小的字符串:

char * example_m_b(type_a a) 

P.S.你怎麼想返回緩衝區PTR允許轉讓的風格和 嵌套函數即

char * example_m_a(type_a a,char * buff,size_t buff_size) 
{ 
... 
return buff; 
} 

回答

3

調用傳遞一個緩衝區和大小一般不容易出錯,特別是如果你的字符串的大小通常是的「合理」的大小。如果你動態地分配內存並返回一個指針,調用者負責釋放內存(並且必須記住根據函數的分配情況,使用相應的內存空閒函數)。

如果您檢查Win32等大型C API,您會發現幾乎所有返回字符串的函數都使用調用者傳遞緩衝區和大小的第一種形式。只有在有限的情況下,你才能找到函數分配返回值的第二種形式(我現在無法想到)。

1

我更喜歡第二個選項,因爲它允許函數決定需要多大的緩衝區。通常呼叫者無法做出該決定。

+0

秒! :) – Vern 2011-05-05 05:10:05

5

將緩衝區作爲參數傳遞可解決大多數此類代碼可能遇到的問題。

如果它返回一個指向緩衝區的指針,那麼你需要決定它如何分配以及調用者是否負責釋放它。該函數可以返回一個不需要釋放的靜態指針,但它不是線程安全的。

+0

我想這與我在其他語言中做事的方式相比,感覺有點難看。 – 2011-05-05 06:43:12

+1

@羅曼:可能是因爲許多現代語言有一個真正的字符串類型,而C沒有。在C中,你必須決定緩衝區的來源。如果調用者提供它,則至少調用者很容易知道內存來自哪裏。 – 2011-05-05 12:50:47

+0

向合唱團傳道。 – 2011-05-06 07:31:04

1

另一替代到通過一個緩衝器和大小樣式,採用一返回代碼:

size_t example_m_a(type_a a,char * buff,size_t buff_size) 

零返回碼指示呼叫方的緩衝液是合適的和已填充在

的返回。代碼> 0表示調用者的緩衝區太小並且顯示實際需要的大小,允許調用者調整其緩衝區並重試。

+0

對我來說這可能有點令人困惑,因爲一些apis在成功時返回字符串的大小,或在失敗時返回0/-1 – 2011-05-05 05:45:33

+0

同意它違背了許多API的規範,但只要它被記錄爲這樣,沒有看到它的問題。當然,像使用size_t * size_needed的第三個參數而不是使用返回碼一樣,可以使用其他口味來滿足您的口味。我的主要觀點是提供靈活的給予調用者失敗的選項(re:David Heffernan的回答)。 – 2011-05-05 05:53:10

0

傳遞緩衝區地址和長度在大多數情況下是最好的。它不太容易出錯,也不必擔心內存泄漏。事實上,在一些緊密的嵌入式系統中,使用堆是完全不希望的。但是,該功能不得超出緩衝區,否則可能導致系統崩潰,甚至更糟糕:使其容易受到黑客的攻擊。

我看到函數返回分配緩衝區的唯一時間是libxml的API,用於從xmlDoc生成XML文本。