C语言中strdup()函数的目的是什么?
当前回答
它通过运行传入字符串的malloc和strcpy来复制传入的字符串。malloc'ed缓冲区返回给调用者,因此需要在返回值上自由运行。
其他回答
它通过运行传入字符串的malloc和strcpy来复制传入的字符串。malloc'ed缓冲区返回给调用者,因此需要在返回值上自由运行。
声明:
strcpy(ptr2, ptr1);
等价于(除了会改变指针):
while(*ptr2++ = *ptr1++);
而:
ptr2 = strdup(ptr1);
等价于:
ptr2 = malloc(strlen(ptr1) + 1);
if (ptr2 != NULL) strcpy(ptr2, ptr1);
所以,如果你想让你复制的字符串被用在另一个函数中(因为它是在堆部分创建的),你可以使用strdup,否则strcpy就足够了,
来自strdup man:
strdup()函数将返回一个指向新字符串的指针,该指针是s1所指向的字符串的副本。返回的指针可以传递给free()。如果不能创建新的字符串,则返回空指针。
就像它听起来一样,假设你习惯了C和UNIX分配单词的缩写方式,它复制了字符串:-)
请记住,它实际上不是当前(C17) 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
}
换句话说:
It tries to allocate enough memory to hold the old string (plus a '\0' character to mark the end of the string). 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). 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).
记住这是概念上的定义。任何有价值的库作者都可能针对所使用的特定处理器提供了大量优化的代码。
另一件需要记住的事情是,根据文档的N2912草案,这看起来是目前计划在标准的C2x迭代中与strndup一起出现。
(a)但是,以str和小写字母开头的函数被标准保留以备将来使用。7.1.3保留标识符:
每个标头声明或定义其关联子句中列出的所有标识符,并可选地声明或定义其关联的未来库方向子句中列出的标识符。*
String .h的未来方向可以在C11 7.31.13字符串处理< String .h>中找到:
以str、mem或wcs和小写字母开头的函数名可以添加到<string.h>头文件的声明中。
所以如果你想安全起见,你应该换个名字。
(b)如果(d == NULL)返回NULL,则更改基本上将被替换;:
if (d == NULL) {
errno = ENOMEM;
return NULL;
}
(c)注意,我使用strcpy,因为它清楚地显示了意图。在某些实现中,使用memcpy可能更快(因为您已经知道长度),因为它们允许以更大的块或并行方式传输数据。-)优化准则#1:“衡量,不要猜测”。
在任何情况下,如果你决定走这条路,你可以这样做:
char *strdup(const char *src) {
size_t len = strlen(src) + 1; // String plus '\0'
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()函数是字符串重复的简写,它接受一个参数作为字符串常量或字符串字面量,并为字符串分配足够的空间,并在分配的空间中写入相应的字符,最后将分配的空间的地址返回给调用例程。