strdup() - 它在 C 中有什么作用? [英] strdup() - what does it do in C?

查看:28
本文介绍了strdup() - 它在 C 中有什么作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C 中 strdup() 函数的用途是什么?

What is the purpose of the strdup() function in C?

推荐答案

正如它所说的那样,假设您习惯了 C 和 UNIX 分配单词的缩写方式,它复制字符串 :-)

Exactly what it sounds like, assuming you're used to the abbreviated way in which C and UNIX assigns words, it duplicates strings :-)

请记住,它实际上不是 ISO C 标准本身的一部分(a)(它是 POSIX 的东西),它实际上与以下代码执行相同的操作:

Keeping in mind it's actually not part of the ISO C standard itself(a) (it's a POSIX thing), it's effectively doing the same as the following code:

char *strdup(const char *src) {
    char *dst = malloc(strlen (src) + 1);  // Space for length plus nul
    if (dst == NULL) return NULL;          // No memory
    strcpy(dst, src);                      // Copy the characters
    return dst;                            // Return the new string
}

换句话说:

  1. 它尝试分配足够的内存来保存旧字符串(加上一个 '' 字符来标记字符串的结尾).

  1. It tries to allocate enough memory to hold the old string (plus a '' character to mark the end of the string).

如果分配失败,则将errno设置为ENOMEM并立即返回NULL.将 errno 设置为 ENOMEMmalloc 在 POSIX 中所做的事情,所以我们不需要在我们的 strdup.如果您 POSIX 兼容,ISO C 实际上并不强制要求 ENOMEM 的存在,所以我没有在此处包含它(b).

If the allocation failed, it sets errno to ENOMEM and returns NULL immediately. Setting of errno to ENOMEM is something malloc does in POSIX so we don't need to explicitly do it in our strdup. If you're not POSIX compliant, ISO C doesn't actually mandate the existence of ENOMEM so I haven't included that here(b).

否则分配会起作用,因此我们将旧字符串复制到新字符串(c) 并返回新地址(调用者负责在某个时间释放该地址).

Otherwise the allocation worked so we copy the old string to the new string(c) and return the new address (which the caller is responsible for freeing at some point).

请记住,这是概念定义.任何物有所值的库编写者都可能提供针对所使用的特定处理器的高度优化的代码.

Keep in mind that's the conceptual definition. Any library writer worth their salary may have provided heavily optimised code targeting the particular processor being used.

(a) 然而,以str 和小写字母开头的函数被标准保留以供将来使用.来自 C11 7.1.3 保留标识符:

(a) However, functions starting with str and a lower case letter are reserved by the standard for future directions. From C11 7.1.3 Reserved identifiers:

每个标题声明或定义其相关子条款中列出的所有标识符,并且*可选地声明或定义其相关的未来库方向子条款中列出的标识符.**

Each header declares or defines all identifiers listed in its associated sub-clause, and *optionally declares or defines identifiers listed in its associated future library directions sub-clause.**

string.h 的未来方向可以在 C11 7.31.13 字符串处理 <string.h> 中找到:

The future directions for string.h can be found in C11 7.31.13 String handling <string.h>:

strmemwcs 开头的函数名称和小写字母可以添加到 中的声明中 标头.

Function names that begin with str, mem, or wcs and a lowercase letter may be added to the declarations in the <string.h> header.

所以如果你想安全的话,你应该叫它别的东西.

So you should probably call it something else if you want to be safe.

(b) 变化基本上是将 if (d == NULL) return NULL; 替换为:

(b) The change would basically be replacing if (d == NULL) return NULL; with:

if (d == NULL) {
    errno = ENOMEM;
    return NULL;
}

<小时>

(c) 请注意,我为此使用了 strcpy,因为这清楚地显示了意图.在某些实现中,使用 memcpy 可能会更快(因为您已经知道长度),因为它们可能允许以更大的块或并行传输数据.或者它可能不会:-) 优化口头禅#1:衡量,不要猜测".


(c) Note that I use strcpy for that since that clearly shows the intent. In some implementations, it may be faster (since you already know the length) to use memcpy, as they may allow for transferring the data in larger chunks, or in parallel. Or it may not :-) Optimisation mantra #1: "measure, don't guess".

无论如何,如果你决定走那条路,你会这样做:

In any case, should you decide to go that route, you would do something like:

char *strdup(const char *src) {
    size_t len = strlen(src) + 1;       // String plus ''
    char *dst = malloc(len);            // Allocate space
    if (dst == NULL) return NULL;       // No memory
    memcpy (dst, src, len);             // Copy the block
    return dst;                         // Return the new string
}

这篇关于strdup() - 它在 C 中有什么作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆