【问题标题】:What is the rationale for not including strdup in the C Standard?在 C 标准中不包括 strdup 的理由是什么?
【发布时间】:2015-10-05 08:41:44
【问题描述】:

大多数 C 程序员都熟悉 strdup 函数。他们中的许多人会认为这是理所当然的,但它不是 C 标准的一部分(C89、C99 和 C11 都不是)。它是 POSIX 的一部分,可能并非在所有环境中都可用。事实上,微软坚持将其重命名为_strdup,这增加了混乱。

用这种方式定义它相当容易(在 C 中):

#include <string.h>

char *strdup(const char *s) {
    size_t size = strlen(s) + 1;
    char *p = malloc(size);
    if (p) {
        memcpy(p, s, size);
    }
    return p;
}

但即使是精明的程序员也很容易出错。

此外,仅在没有该功能的系统上重新定义该功能证明有点复杂,如下所述:strdup() function

为什么不在 C 标准的修订版中包含这些广泛支持的有用功能? C99的C标准库中增加了很多新函数,不包括strdup的原因是什么?

【问题讨论】:

  • @AlterMann: malloc 和朋友一直是 C 标准的一部分。 aligned_alloc 是在 C11 中添加的,malloc 在 C11 标准的 11 页中提到,你能解释一下你的意思吗?
  • @AlterMann:不是每个人都在为嵌入式系统编程。如果本地规则禁止通过malloc 分配内存,他们显然也应该禁止strdup
  • 很遗憾C语言的进化是由这么小的4个人决定的,其中一半似乎并不在意。
  • @JensGustedt 我认为他的意思是如果我们同时添加strdupaprintf,那么就不能再争论strdup 将是唯一不以@ 结尾的函数987654336@ 需要 free 获得结果

标签: c standards


【解决方案1】:

cmets (http://open-std.org/JTC1/SC22/WG14/www/docs/n718.htm) 中的引用链接解释了在标准库中使用 strdup 的“错误”:

主要问题是希望向标准库添加一个自动为用户分配堆内存的函数。

基本上,C 语言及其标准库尽量不对用户如何分配和使用内存做出假设。
它提供了一些设施,其中包括堆栈和堆。

虽然 malloc/free 已针对动态内存分配进行了标准化,但它们绝不是唯一的方法,因为动态内存管理是一个非常复杂的主题,并且默认分配策略可能不适用于所有类型的应用程序。

例如有一些独立的库,例如强调低碎片和并发性的jemalloc,甚至还有成熟的垃圾收集器,例如The Boehm-Demers-Weiser conservative garbage collector。 这些库提供 malloc/free 实现,专门用于替代标准 *alloc 和来自 &lt;stdlib.h&gt; 的 free 函数,而不会破坏与 C 标准库其余部分的兼容性。

因此,如果 strdup 成为标准,它将被使用第三方内存管理函数的代码有效地取消资格(必须注意,前面提到的 jemalloc 库确实提供了 strdup 的实现来避免这个问题)。

更一般地说,虽然 strdup 确实是一个实用函数,但它的语义不够清晰。它是在&lt;string.h&gt; 标头中声明的函数,但调用它需要通过从&lt;stdlib.h&gt; 标头调用free 函数来释放返回的缓冲区。那么,到底是字符串函数还是记忆函数呢?
将其留在 POSIX 标准中似乎是避免使 C 标准库不太清晰的最合理的解决方案。

【讨论】:

  • 我理解你的论点,但我觉得这个答案不是很有说服力:strdup 被广泛使用,以至于许多专业 C 程序员认为它是标准的一部分(询问你自己的开发人员)。 malloc 系列函数的所有替代实现也提供了 strdup 的替代品,Boehm gc 或任何其他功能都不会因 strdup 成为标准而被击败。头问题不是问题,最坏的情况是strdup 可以在&lt;stdlib.h&gt;&lt;string.h&gt; 中定义,就像在多个标准头文件中定义的NULL 一样。
  • @chqrlie 作为一个例外可能会起作用,但想象一下,如果使用类似分配模式的函数开始标准化,这意味着每个替代 malloc 实现都必须发布它们自己的这些函数版本,并最终发布他们自己的 C 标准库版本。那将是一场维护噩梦。
  • 为了完整起见,NULL 定义在 &lt;stdio.h&gt;&lt;stdlib.h&gt;&lt;string.h&gt;&lt;time.h&gt;&lt;wchar.h&gt;&lt;locale.h&gt;&lt;stddef.h&gt;...
  • 在我的辩护中,鉴于前面提到的投票结果好坏参半,我不能假装提出比标准委员会本身更有说服力的反对 strdup 的理由。老实说,我之前在我的代码中使用过 strdup,但我不能说我非常喜欢这个函数,因为我更喜欢 malloc 和 free 位于同一抽象级别。当您自己没有调用 malloc 时,很容易忘记调用 free。
  • 请注意&lt;string.h&gt; 包含strerror(),但您需要&lt;errno.h&gt; 来获取errno 值或宏,然后您可以将其传递给strerror()strdup() 不适用于 &lt;string.h&gt; 的建议仅具有边际相关性——尽管这有一定的道理。
猜你喜欢
  • 2010-09-20
  • 2011-08-30
  • 1970-01-01
  • 1970-01-01
  • 2015-05-31
  • 2016-01-29
  • 2016-02-17
  • 1970-01-01
相关资源
最近更新 更多