我了解到strcpy
函数用于复制字符串,而strdup
函数返回指向新字符串的指针以复制该字符串。
您能否解释一下在哪些情况下您更喜欢使用strcpy
和在哪些情况下您更喜欢使用strdup
?
strcpy(ptr2, ptr1)
相当于 while(*ptr2++ = *ptr1++)
而 strdup
则相当于
ptr2 = malloc(strlen(ptr1)+1);
strcpy(ptr2,ptr1);
(memcpy版本可能更有效率)
所以如果你想要将复制的字符串在另一个函数中使用(因为它是在堆区域创建的), 你可以使用strdup, 否则strcpy就足够了。
strcpy
和 strncpy
函数是 C 标准库中的函数,用于操作已有的内存。也就是说,你 必须提供内存让这些函数将字符串数据复制进去,而且作为一个必然的结果,你 必须自己找出需要多少内存。
相比之下,strdup
是一个 Posix 函数,它会为你执行动态内存分配。它返回指向新分配内存的指针,并且已经将字符串复制到了这块内存中。但是,你 现在负责这块内存并最终必须使用 free
释放掉它。
这使得 strdup
成为“隐藏的 malloc
”便利函数之一,这也可能是它不是标准库的一部分的原因。只要你使用标准库,就知道调用每个 malloc
/calloc
后必须调用一个 free
。但是像 strdup
这样的函数引入了一个隐藏的 malloc
,你必须像管理内存时处理 malloc
一样来处理它。(另一个类似的隐藏分配函数是 GCC 的 abi::__cxa_demangle()
。)请注意!
strdup
会在堆上分配内存用于新字符串,而使用 strcpy
(或更安全的 strncpy
变体),我可以将一个字符串复制到已经在堆或栈上预先分配好的内存中。
strcpy
将内容复制到静态缓冲区中吗? - Kerrek SBstrdup
的实现如下所示:ptr2 = malloc(strlen(ptr1)+1);
strcpy(ptr2,ptr1);
然而,那有点次优,因为strlen
和strcpy
都需要通过检查每个字符是否为\0
来找到字符串的长度。
使用memcpy
应该更有效率:
char *strdup(const char *src) {
size_t len = strlen(src) + 1;
char *s = malloc(len);
if (s == NULL)
return NULL;
return (char *)memcpy(s, src, len);
}
strcpy
的概念用于实现strdup
与以高效的方式实现它的实际可行性分开。 - Michael Gaskillwhile (len--) { *ptr2++ = *ptr1++ }
,每次进行减法、赋值和零测试,然后仍然必须运行一个赋值,然后是两个后增量及其赋值。因此,这种memcpy技术似乎不太高效。这些似乎是相当琐碎的区别和想象中的优化。 - user2895783char *strdup(char *pszSrch)
;
strdup
函数将分配与原始字符串相同大小的存储空间。如果存储分配成功,则将原始字符串复制到副本字符串中。
strdup
在失败时返回NULL
。如果未分配内存,复制失败,则strdup
返回NULL
。
对于*memcpy,可以使用另一种实现方式,而不需要增加dest和src的增量:
while ( n-- ) { dest[n] = src[n] }
strdup()
函数创建的字符串的生命周期可以超出当前函数的末尾,但这种情况本来就可能存在(如果strcpy()
的目标是调用者提供的缓冲区、全局变量或手动使用malloc()
或new
分配的内存)。 - j_random_hackerwhile(*ptr2++ = *ptr1++)
! :) - Aloyswhile(*ptr2++ = *ptr1++)
,不要忘记将指针恢复到它们的原始值。在while
结束后,它们将位于空终止符位置。 - Paulo Carvalho