【发布时间】:2012-12-10 19:39:06
【问题描述】:
我读到strcpy 用于复制字符串,strdup 返回指向新字符串的指针以复制字符串。
能否请您解释一下您更喜欢使用哪些情况strcpy,以及您更喜欢使用哪些情况strdup?
【问题讨论】:
我读到strcpy 用于复制字符串,strdup 返回指向新字符串的指针以复制字符串。
能否请您解释一下您更喜欢使用哪些情况strcpy,以及您更喜欢使用哪些情况strdup?
【问题讨论】:
strdup 为堆上的新字符串分配内存,而使用strcpy(或更安全的strncpy 变体)我可以将字符串复制到任一上的预分配内存堆或栈。
【讨论】:
strcpy复制到静态缓冲区?
strcpy(ptr2, ptr1) 等价于while(*ptr2++ = *ptr1++)
strdup 等价于
ptr2 = malloc(strlen(ptr1)+1);
strcpy(ptr2,ptr1);
(memcpy version 可能更高效)
因此,如果您希望复制的字符串在另一个函数中使用(因为它是在堆部分创建的),您可以使用 strdup,否则 strcpy 就足够了。
【讨论】:
strdup()ed 字符串的生命周期可以超出当前函数的结尾,但无论如何都可能是这种情况(如果strcpy() 的目标是调用者提供的缓冲区、全局变量或本身使用malloc() 或new 手动分配)。
while(*ptr2++ = *ptr1++)! :)
函数strcpy 和strncpy 是C 标准库的一部分,对现有内存进行操作。也就是说,you 必须提供函数将字符串数据复制到其中的内存,并且作为推论,you 必须有自己的方法来找出需要多少内存.
相比之下,strdup 是一个 Posix 函数,它为您执行动态内存分配。它返回一个指向新分配的内存的指针,它已将字符串复制到该内存中。但是你现在要对这段记忆负责,并且最终必须free它。
这使得strdup 成为“隐藏的malloc”便利函数之一,这可能也是它不属于标准库的原因。只要你使用标准库,你就知道你必须为每个malloc/calloc调用一个free。但是像strdup这样的函数引入了一个隐藏的malloc,为了内存管理,你必须把它和malloc一样对待。 (另一个这样的隐藏分配函数是 GCC 的abi::__cxa_demangle()。)小心!
【讨论】:
char *strdup(char *pszSrch);
strdup 将分配原始字符串大小的存储空间。如果存储分配成功,则将原始字符串复制到重复字符串。
strdupd 失败时返回NULL。如果未分配内存,则复制失败strdup 返回NULL。
【讨论】:
在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 的实用性区分开来。
while ( len-- ) { *ptr2++ = *ptr1++ },它每次都会进行减法、赋值和测试为零,然后仍然必须运行一个赋值,然后是两个后增量和它们的赋值。所以这种 memcpy 技术似乎效率较低。这些似乎是微不足道的区别和想象中的优化。