为什么strdup被认为是邪恶的

时间:2012-10-20 03:18:59

标签: c c-strings

我看到一些海报说明strdup是邪恶的。对此有共识吗?我使用它没有任何内疚感,并且没有理由比使用malloc / memcpy更糟糕。

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


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

真的没有'正确'的答案,但是为了接受一个,我接受了@nneoneo的答案 - 它同样可能是@R ..的答案。

6 个答案:

答案 0 :(得分:31)

我能想到的两个原因:

  1. 它不是严格的ANSI C,而是POSIX。因此,一些编译器(例如MSVC)不鼓励使用(MSVC更喜欢_strdup),而技术上 C标准可以定义自己的strdup具有不同的语义,因为str是保留的前缀。因此,使用它有一些潜在的可移植性问题。
  2. 它隐藏了内存分配。大多数其他str函数不分配内存,因此用户可能被误导(如您所说),相信不需要释放返回的字符串。
  3. 但是,除了这些要点之外,我认为谨慎使用strdup是合理的,因为它可以减少代码重复并为常见习语提供一个很好的实现(例如strdup("constant string")以获得可变的,文字字符串的可返回副本。)

答案 1 :(得分:19)

我的回答是支持strdup而且它并不比C中的任何其他功能更糟糕。

  1. 如果可移植性成为问题,POSIX是标准并且strdup并不太难实现。

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

    < / LI>
  3. 在C,记忆&amp;大多数其他东西都是由程序员管理的,所以strdup并不比忘记 free malloc'内存,没有 null终止字符串,使用不正确格式字符串scanf(并调用未定义的行为),访问悬空指针等。

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

答案 2 :(得分:10)

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

  1. 它不是标准C(但在POSIX中)。但是我发现这个理由很愚蠢,因为在缺少它的系统上添加它几乎是一行功能。
  2. 盲目地复制整个地方的字符串,而不是在可能的情况下就地使用它们浪费时间和内存,并将故障情况引入可能无故障的代码中。
  3. 当你确实需要一个字符串的副本时,你可能真的需要更多的空间来修改或构建它,而strdup并没有给你这个。

答案 3 :(得分:5)

我认为对strdup的大多数关注来自于缓冲区运行和格式不正确的字符串的安全问题。如果将非空终止字符串传递给strdup,则可以分配未定义的长度字符串。我不知道这是否可以专门用于攻击,但一般来说,良好的安全编码习惯只能使用占用最大长度的字符串函数,而不是单独依赖空字符。

答案 4 :(得分:2)

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

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

  • 它总是在堆上分配内存,而对于C99(是99?)的VLA,还有另一个原因就是使用strcpy(你甚至不需要malloc )。你不能总是这样做,但是当你可以的时候,你应该这样做。

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

这些当然是我自己的一些原因,没有其他人的原因。为了回答你的问题,我没有达成共识。

如果你正在为自己编写程序并且发现strdup没有问题,那么没有理由不使用它,而不是你正在编写一个程序,以便被许多技能水平的许多人阅读。年龄。

答案 5 :(得分:1)

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

实际上,strdup的答案当然是free,而且该功能本来更好地命名为malloc_and_strcpy以明确这一点。但是很多C程序员都没有想到这一点而忘记了strdup需要它的反面或者#34;结束&#34; free要解除分配。

根据我的经验,在调用strdup的代码中发现内存泄漏是很常见的。这是一个奇怪的功能,它结合了strlenmallocstrcpy