strcpy 与 strdup
Posted
技术标签:
【中文标题】strcpy 与 strdup【英文标题】:strcpy vs strdup 【发布时间】:2012-12-10 19:39:06 【问题描述】:我读到strcpy
用于复制字符串,strdup
返回指向新字符串的指针以复制字符串。
能否请您解释一下您更喜欢使用哪些情况strcpy
,以及您更喜欢使用哪些情况strdup
?
【问题讨论】:
【参考方案1】:strdup
为堆上的新字符串分配内存,而使用strcpy
(或更安全的strncpy
变体)我可以将字符串复制到任一上的预分配内存堆或栈。
【讨论】:
为什么要强调“要么”?是不是不能用strcpy
复制到静态缓冲区?
我试图强调这两个函数在使用上的差异,但不会因为太多的内存管理问题而使答案混乱。但是是的,您对静态缓冲区的看法是正确的。
如果你不想杂乱无章,你可以在“预分配内存”之后结束答案:-)
small nitpick:strncpy 并不比 strcpy 安全,因为它不能保证 dest 会以空值终止。更糟糕的是,dest 缓冲区中任何未使用的空间都将被空终止符填充。此功能从未用于一般用途。如果必须使用这些函数之一,最好使用 strcpy 并手动终止 dest。【参考方案2】:
strcpy(ptr2, ptr1)
等价于while(*ptr2++ = *ptr1++)
strdup 等价于
ptr2 = malloc(strlen(ptr1)+1);
strcpy(ptr2,ptr1);
(memcpy version 可能更高效)
因此,如果您希望复制的字符串在另一个函数中使用(因为它是在堆部分创建的),您可以使用 strdup,否则 strcpy 就足够了。
【讨论】:
除了最后一句话之外的好答案,这令人困惑。我猜你的意思是strdup()
ed 字符串的生命周期可以超出当前函数的结尾,但无论如何都可能是这种情况(如果strcpy()
的目标是调用者提供的缓冲区、全局变量或本身使用malloc()
或new
手动分配)。
是的,如果调用者提供的缓冲区本身是一个全局变量或动态指针,那么就不需要使用 strdup 我刚刚指出了一个用例场景并感谢您完成它.
真的很喜欢while(*ptr2++ = *ptr1++)
! :)
在while循环中,退出条件是如何工作的?
@sbhatla 在 C 中,字符串以 nulbyte 结尾,计算结果为 false,赋值表达式计算为分配的值。【参考方案3】:
函数strcpy
和strncpy
是C 标准库的一部分,对现有内存进行操作。也就是说,you 必须提供函数将字符串数据复制到其中的内存,并且作为推论,you 必须有自己的方法来找出需要多少内存.
相比之下,strdup
是一个 Posix 函数,它为您执行动态内存分配。它返回一个指向新分配的内存的指针,它已将字符串复制到该内存中。但是你现在要对这段记忆负责,并且最终必须free
它。
这使得strdup
成为“隐藏的malloc
”便利函数之一,这可能也是它不属于标准库的原因。只要你使用标准库,你就知道你必须为每个malloc
/calloc
调用一个free
。但是像strdup
这样的函数引入了一个隐藏的malloc
,为了内存管理,你必须把它和malloc
一样对待。 (另一个这样的隐藏分配函数是 GCC 的abi::__cxa_demangle()
。)小心!
【讨论】:
啊,我一直想知道为什么这不在 stdlib 中,现在我知道了。【参考方案4】:char *strdup(char *pszSrch)
;
strdup
将分配原始字符串大小的存储空间。如果存储分配成功,则将原始字符串复制到重复字符串。
strdup
d 失败时返回NULL
。如果未分配内存,则复制失败strdup
返回NULL
。
【讨论】:
【参考方案5】:在accepted answer中,strdup
的实现表现为:
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
的实用性区分开来。
鉴于 memcpy 依赖于知道字符串长度,无论哪种情况都会调用 strlen。 memcpy 本身等同于while ( len-- ) *ptr2++ = *ptr1++
,它每次都会进行减法、赋值和测试为零,然后仍然必须运行一个赋值,然后是两个后增量和它们的赋值。所以这种 memcpy 技术似乎效率较低。这些似乎是微不足道的区别和想象中的优化。以上是关于strcpy 与 strdup的主要内容,如果未能解决你的问题,请参考以下文章