C语言中strdup()函数的目的是什么?
当前回答
char * strdup(const char * s)
{
size_t len = 1+strlen(s);
char *p = malloc(len);
return p ? memcpy(p, s, len) : NULL;
}
也许代码比strcpy()快一点,因为\0字符不需要再次搜索(它已经使用strlen())。
其他回答
Strdup()对包含结束字符'\0'的字符数组进行动态内存分配,并返回堆内存地址:
char *strdup (const char *s)
{
char *p = malloc (strlen (s) + 1); // allocate memory
if (p != NULL)
strcpy (p,s); // copy string
return p; // return the memory
}
所以,它所做的是给我们另一个与它的参数所给出的字符串相同的字符串,而不需要我们分配内存。但我们仍然需要稍后释放它。
strdup()函数是字符串重复的简写,它接受一个参数作为字符串常量或字符串字面量,并为字符串分配足够的空间,并在分配的空间中写入相应的字符,最后将分配的空间的地址返回给调用例程。
它所做的最有价值的事情是为您提供与第一个相同的另一个字符串,而不需要您自己分配内存(位置和大小)。但是,如前所述,您仍然需要释放它(但这也不需要进行数量计算)。
它通过运行传入字符串的malloc和strcpy来复制传入的字符串。malloc'ed缓冲区返回给调用者,因此需要在返回值上自由运行。
就像它听起来一样,假设你习惯了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
}