C语言 为什么 strdup 被认为是邪恶的

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12984948/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:10:04  来源:igfitidea点击:

Why is strdup considered to be evil

cc-strings

提问by William Morris

I've seen some posters stating that strdupis evil. Is there a consensus on this? I've used it without any guilty feelings and can see no reason why it is worse than using malloc/memcpy.

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

The only thing I can think might earn strdupa reputation is that callers might misuse it (eg. not realise they have to free the memory returned; try to strcat to the end of a strdup'ed string). But then malloc'ed strings are not free from the possibility of misuse either.

我认为唯一可能赢得strdup声誉的是调用者可能会滥用它(例如,没有意识到他们必须释放返回的内存;尝试 strcat 到 strdup 字符串的末尾)。但是,经过 malloc 处理的字符串也存在误用的可能性。



Thanks for the replies and apologies to those who consider the question unhelpful (votes to close). In summary of the replies, it seems that there is no general feeling that strdupis evil per se, but a general consensus that it can, like many other parts of C, be used improperly or unsafely.

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

There is no 'correct' answer really, but for the sake of accepting one, I accepted @nneoneo's answer - it could equally have been @R..'s answer.

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

回答by nneonneo

Two reasons I can think of:

我能想到的两个原因:

  1. It's not strictly ANSI C, but rather POSIX. Consequently, some compilers (e.g. MSVC) discourage use (MSVC prefers _strdup), and technicallythe C standard could define its own strdupwith different semantics since stris a reserved prefix. So, there are some potential portability concerns with its use.
  2. It hides its memory allocation. Most other strfunctions don't allocate memory, so users might be misled (as you say) into believing the returned string doesn't need to be freed.
  1. 它不是严格意义上的 ANSI C,而是 POSIX。因此,一些编译器(例如 MSVC)不鼓励使用(MSVC 更喜欢_strdup),并且从技术上讲,C 标准可以定义自己strdup的不同语义,因为str是保留前缀。因此,它的使用存在一些潜在的便携性问题。
  2. 它隐藏了它的内存分配。大多数其他str函数不分配内存,因此用户可能会被误导(如您所说)相信返回的字符串不需要被释放。

But, aside from these points, I think that careful use of strdupis justified, as it can reduce code duplication and provides a nice implementation for common idioms (such as strdup("constant string")to get a mutable, returnable copy of a literal string).

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

回答by P.P

My answer is rather supporting strdupand it is no worse than any other function in C.

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

  1. POSIX is a standardand strdupis not too difficult to implement if portability becomes an issue.

  2. Whether to free the memory allocated by strdupshouldn't be an issue if anyone taken a little time to read the man page and understand how strdupworks. If one doesn't understand how a function works, it's very likely the person is going to mess up something, this is applicable to anyfunction, not just strdup.

  3. In C, memory & most other things are managed by the programmer, so strdup is no worse than forgetting to freemalloc'ed memory, failing to null terminatea string, using incorrect format string in scanf(and invoking undefined behaviour), accessing danglingpointer etc.

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

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

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

(I really wanted to post this as a comment, but couldn't add in a single comment. Hence, posted it as an answer).

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

回答by R.. GitHub STOP HELPING ICE

I haven't really heard strdupdescribed as evil, but some possible reasons some people dislike it:

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

  1. It's not standard C (but is in POSIX). However I find this reason silly because it's nearly a one-line function to add on systems that lack it.
  2. Blindly duplicating strings all over the place rather than using them in-place when possible wastes time and memory and introduces failure cases into code that might otherwise be failure-free.
  3. When you do need a copy of a string, it's likely you actually need more space to modify or build on it, and strdupdoes not give you that.
  1. 它不是标准 C(但在 POSIX 中)。然而,我觉得这个原因很愚蠢,因为在缺少它的系统上添加几乎是一个单行功能。
  2. 盲目地在所有地方复制字符串而不是在可能的情况下就地使用它们会浪费时间和内存,并将失败案例引入可能无故障的代码中。
  3. 当您确实需要一个字符串的副本时,很可能您实际上需要更多空间来修改或构建它,而这strdup并没有给您。

回答by john-charles

I think the majority of the concern about strdup comes from security concerns regarding buffer over runs, and improperly formatted strings. If a non-null terminated string is passed to strdup it can allocated an undefined length string. I don't know if this can be specifically leveraged into an attack but in general it is good secure coding practice to only use string functions which take a maximum length instead of relying on the null character alone.

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

回答by Seth Carnegie

Many people obviously don't, but I personally find strdupevil for several reasons,

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

  • the main one being it hides the allocation. The other str*functions and most other standard functions require no freeafterwards, so strduplooks innocuous enough and you can forget to clean up after it. dmckee suggested to just add it to your mental list of functions that need cleaning up after, but why? I don't see a big advantage over reducing two medium-length lines to one short one.

  • It allocates memory on the heap always, and with C99's (is it 99?) VLAs, you have yet another reason to just use strcpy(you don't even need malloc). You can't always do this, but when you can, you should.

  • It's not part of the ISO standard (but it is part of the POSIX standard, thanks Wiz), but that's really a small point as R.. mentioned that it can be added easily. If you write portable programs, I'm not sure how you'd tell if it was already defined or not though...

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

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

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

These are of course a few of my own reasons, no one else's. To answer your question, there is no consensus that I'm aware of.

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

If you're writing programs just for yourself and you find strdupno problem, then there's much less reason not to use it than if you are writing a program to be read by many people of many skill levels and ages.

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

回答by Bj?rn Lindqvist

My reason for disliking strdup, which hasn't been mentioned, is that it is resource allocation without a natural pair. Let's try a silly game: I say malloc, you say free. I say openyou say close. I say createyou say destroy. I say strdupyou say ....?

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

Actually, the answer to strdupis freeof course, and the function would have been better named malloc_and_strcpyto make that clear. But many C programmers don't think of it that way and forgets that strduprequires its opposite or "ending" freeto deallocate.

其实,答案strdupfree当然的,而且功能会被更好地命名malloc_and_strcpy,以表明这一点。但是许多 C 程序员并不这么认为,并且忘记了strdup需要它的对立面或“结束”free才能解除分配。

In my experience, it is very common to find memory leaks in code which calls strdup. It's an odd function which combines strlen, mallocand strcpy.

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