当前位置:  开发笔记 > 编程语言 > 正文

strdup() - 它在C中做了什么?

如何解决《strdup()-它在C中做了什么?》经验,为你挑选了4个好方法。

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



1> paxdiablo..:

究竟是什么样的,假设你已经习惯了C和UNIX分配单词的缩写方式,它会复制字符串 :-)

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

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
}

换一种说法:

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

    如果分配失败,则设置errnoENOMEMNULL立即返回.在POSIX中设置errnoto ENOMEM是有效的malloc,所以我们不需要在我们的中明确地执行它strdup.如果你符合POSIX标准,那么ISO C实际上并没有强制要求存在,ENOMEM所以我没有把它包括在这里(b).

    否则分配工作,所以我们将旧字符串复制到新字符串并返回新地址(调用者负责在某个时候释放).

请记住,这是概念性的定义.任何值得他们工资的图书馆作家都可能提供针对所使用的特定处理器的大量优化代码.


(a)但请注意,str标准为未来指示保留以小写字母开头的函数和小写字母.来自C11 7.1.3 Reserved identifiers:

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

未来的方向string.h可以在C11 7.31.13 String handling :

str,memwcs小写字母开头的函数名称可以添加到标题中的声明中.


(b)改变基本上将取代if (d == NULL) return NULL;:

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


值得注意的是,正如Pax的示例实现暗示的那样,strdup(NULL)是未定义的,而不是您可以期望以任何可预测的方式运行的东西.
@Alcot,`strdup`适用于那些需要为字符串副本分配堆内存的情况.否则你必须自己做.如果你已经_have_足够大的缓冲区(malloc'ed或其他),是的,使用`strcpy`.
另外,我认为malloc()会设置errno,所以你不必自己设置它.我认为.
@acgtyrant:如果,按标准,你的意思是ISO标准(真正的C标准),不,它不是它的一部分.它是POSIX标准的一部分.然而,有很多C _implementations_提供它,尽管不是ISO C的官方部分.但是,即使他们没有,这个答案中的五线应该是绰绰有余的.
好的,@ chux,ISO只要求`{EDOM,EILSEQ,ERANGE}`作为必需的错误代码.已更新答案以解释此问题.

2> Patrick Schl..:
char * strdup(const char * s)
{
  size_t len = 1+strlen(s);
  char *p = malloc(len);

  return p ? memcpy(p, s, len) : NULL;
}

也许代码比使用char 更快一些,strcpy()因为\0char不需要再次搜索(它已经存在strlen()).


@tristopia解除引用`NULL`不必崩溃; 这是未定义的.如果你想确定它崩溃了,写一个`emalloc`,在失败时调用`abort`.

3> Chris Young..:

没有必要重复其他答案,但请注意,strdup()从C角度来看,它可以做任何想做的事情,因为它不是任何C标准的一部分.但是它由POSIX.1-2001定义.


`strdup()`便携吗?不,在非POSIX环境中不可用(无论如何都可以实现).但是说POSIX功能可以做任何事情是非常迂腐的.POSIX是另一个*标准*,它与C一样好,甚至更受欢迎.
@BlueMoon我认为重点是声称不符合POSIX的C实现仍然可以提供`strdup`函数作为扩展.在这样的实现中,不能保证`strdup`的行为与POSIX函数的行为相同.我不知道任何这样的实现,但合法的非恶意实现可能会出于历史原因提供`char*strdup(char*)`,并拒绝传递`const char*`的尝试.

4> VonC..:

来自strdup man:

strdup()函数应返回一个指向新字符串的指针,该字符串是指向的字符串的副本s1.返回的指针可以传递给free().如果无法创建新字符串,则返回空指针.

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有