2011-05-05 61 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文本。