30

我看过一些海报说这strdup是邪恶的。对此是否有共识?我使用它时没有任何内疚感,并且看不出它比使用malloc/更糟糕的原因memcpy

我能想到的唯一可能赢得strdup声誉的是调用者可能会滥用它(例如,没有意识到他们必须释放返回的内存;尝试将 strcat 放到 strdup 字符串的末尾)。但是,malloc'ed 字符串也不是没有被滥用的可能性。


感谢那些认为这个问题没有帮助的人的回复和道歉(投票结束)。总结这些回复,似乎没有普遍的感觉strdup本身就是邪恶的,而是普遍认为它可以像 C 的许多其他部分一样被不当或不安全地使用。

确实没有“正确”的答案,但为了接受一个,我接受了@nneoneo 的答案——它同样可能是@R.. 的答案。

4

6 回答 6

35

我能想到的两个原因:

  1. 它不是严格的 ANSI C,而是 POSIX。因此,一些编译器(例如 MSVC)不鼓励使用(MSVC 更喜欢_strdup),并且从技术上讲strdup,C 标准可以用不同的语义定义自己的,因为str它是一个保留的前缀。因此,它的使用存在一些潜在的可移植性问题。
  2. 它隐藏了它的内存分配。大多数其他str函数不分配内存,因此用户可能会被误导(如您所说)相信返回的字符串不需要被释放。

但是,除此之外,我认为谨慎使用strdup是合理的,因为它可以减少代码重复并为常见的习惯用法提供了一个很好的实现(例如strdup("constant string")获取一个可变的、可返回的文本字符串副本)。

于 2012-10-20T03:25:15.327 回答
21

我的回答是相当支持的strdup,它并不比 C 中的任何其他函数差。

  1. POSIX 是一种标准strdup如果可移植性成为问题,实施起来并不难。

  2. strdup如果有人花一点时间阅读手册页并了解其工作原理,是否释放分配的内存应该不是问题strdup。如果一个人不了解一个函数是如何工作的,那么这个人很可能会搞砸一些事情,这适用于任何函数,而不仅仅是strdup.

  3. 在 C 中,内存和大多数其他东西都由程序员管理,因此 strdup 并不比忘记释放 malloc内存、未能为空终止字符串、使用不正确的格式字符串scanf(并调用未定义的行为)、访问悬空指针等更糟糕.

(我真的很想将此作为评论发布,但无法添加一条评论。因此,将其发布为答案)。

于 2012-10-20T23:24:06.517 回答
10

我还没有真正听说过strdup被描述为邪恶,但有些人不喜欢它的一些可能原因:

  1. 它不是标准的 C(但在 POSIX 中)。但是我觉得这个原因很愚蠢,因为它几乎是一个添加到缺少它的系统的单行函数。
  2. 盲目地在各处复制字符串,而不是在可能的情况下就地使用它们会浪费时间和内存,并将失败案例引入可能没有失败的代码中。
  3. 当您确实需要一个字符串的副本时,您实际上可能需要更多空间来修改或构建它,strdup但并没有给您。
于 2012-10-20T03:26:42.413 回答
5

我认为对 strdup 的大部分担忧来自于关于缓冲区溢出和格式不正确的字符串的安全问题。如果将非空终止字符串传递给 strdup,它可以分配一个未定义长度的字符串。我不知道这是否可以专门用于攻击,但总的来说,仅使用具有最大长度的字符串函数而不是单独依赖空字符是一种很好的安全编码实践。

于 2012-10-20T05:05:54.623 回答
2

很多人显然不知道,但我个人认为strdup邪恶有几个原因,

  • 主要的是它隐藏了分配。其他str*功能和大多数其他标准功能都不需要free事后处理,所以strdup看起来很无害,你可以忘记在它之后进行清理。dmckee 建议将其添加到您需要清理的功能的心理列表中,但为什么呢?与将两条中等长度的线减少到一条短线相比,我认为没有太大的优势。

  • 它总是在堆上分配内存,并且使用 C99(是 99?)VLA,您还有另一个理由只使用strcpy(您甚至不需要malloc)。你不能总是这样做,但当你可以的时候,你应该这样做。

  • 它不是 ISO 标准的一部分(但它是 POSIX 标准的一部分,感谢 Wiz),但这确实是一个小问题,因为 R.. 提到它可以很容易地添加。如果您编写可移植程序,我不确定您如何判断它是否已经定义...

这些当然是我自己的一些原因,没有其他人的。要回答你的问题,我知道没有共识。

如果您只是为自己编写程序并且您没有发现strdup任何问题,那么没有理由不使用它,而不是您正在编写一个可供许多不同技能水平和年龄的人阅读的程序。

于 2012-10-20T04:13:39.900 回答
1

我不喜欢 strdup 的原因是没有自然对的资源分配。让我们尝试一个愚蠢的游戏:我说malloc,你说free。我说open你说close。我说create你说destroy。我说strdup你说……?

实际上,答案当然strdupfree,并且该函数的名称应该更好地malloc_and_strcpy说明这一点。但是许多 C 程序员并不这样想,并且忘记了strdup需要它的相反或“结束”free来解除分配。

根据我的经验,在调用strdup. 这是一个奇函数,它结合strlenmallocstrcpy

于 2016-05-30T03:55:28.877 回答