什么时候使用strdup是个好主意(vs malloc / strcpy)

我可以使用mallocstrcpy来替换它吗? 哪一个更好?

例如:

 char *s = "Global View"; char *d; d = strdup(s); free(d); 

要么

 char *s = "Global View"; char *d = malloc(strlen(s) +1); strcpy(d,s); free(d); 

哪一个更好?

strdup(s); 当分配失败时(调用代码仍然需要处理 NULL返回)本身不会产生问题,这与下面的未定义行为或UB不同。

 char *d = malloc(strlen(s) +1); strcpy(d,s); // should not be called if `d == NULL`. 

strdup(s)典型实现不会像备用的那样走两次s的长度。

 // 1st pass to find length of `s` char *d = malloc(strlen(s) +1); // Weak compiler/library may run 2nd pass to find length of `s` and then copy strcpy(d,s); 

一个好的strdup(s)将进行一次通过并在长度保证时使用最佳复制代码。 也许通过使用memcpy()或等效的。

关键是strdup()预计会经常使用,并且实现这种非标准C库函数的可以精心设计以实现最佳性能。 可用时使用最好的工具。 示例实施:

 char *strdup(const char *s) { if (s == NULL) { // Optional test, s should point to a string return NULL; } size_t siz = strlen(s) + 1; char *y = malloc(siz); if (y != NULL) { memcpy(y, s, siz); } return y; } 

滚动你自己的strdup()确实与保留的名字空间@Jonathan Leffler @Joshua相撞

malloc()/memcpy()/strcpy()一个重要优点是它们是标准的C库函数。 strdup()不在标准C库中,尽管它是非常常见的

除了strdup被缩短之外没有太大的区别。 strdup == malloc + strcpy

我建议使用strdup()。 而malloc()+ memcpy()只有大字符串,你知道实际的大小。 这样可以节省获取字符串的时间以获得长度。 由于这是一个非常快速的function,您可以欣赏仅几兆字节文本的差异。 假设你有一个结构字符串

  typedef struct string { char* st; long buf; long n; } String; 

在这种情况下,你可以获得字符串的实际大小,所以如果我应该strdup()这个字符串我会写:

  char * stringdup(String *st) { char *res=malloc(st->n); res?memcpy(res,st->st,st->n):NULL; } 

您可以注意到一些事情:当我复制字符串时,我返回一个char *而不是String。 经验说结构字符串很好用于构建字符串,但用于存储字符串并不舒服。 因为所有调试器都可以将char *显示为字符串,但没有人会知道您的结构。 因此,一旦定义了最终字符串,最好离开struct。 节省空间,调试速度更快。 这也是因为对于小文本的解释,不值得使用这样的说明。 你永远不会欣赏它,但它会弄乱你的代码。

更新:

我忘了另一种情况。 当您只需要复制字符串的一个子集时,可以使用malloc()+ memcpy()。 strdup()和strcpy()将复制所有内容。 但是,如果您只想要文本的一部分,则应使用这些说明。

使用strdup()在使用libc字符串处理函数时保持一致。 strdup()意味着操作数是libc的以null结尾的字符串的模型。

libc的str...()函数完美地解决了C字符串处理的基础知识,所以只要它们足够就可以使用它们,除非是为了让你的代码更快地被其他人理解,并且避免编写超过必要的代码。

我个人不会在没有令人信服的理由的情况下混合模型。 可能出现这样的情况,即使用自定义函数补充libc字符串函数是有帮助的或必要的,或者可能完全绕过它们,例如,并非所有C平台都提供libc。 也许存在链接问题,或者您在内核上下文中工作并且无法在没有崩溃或大量工作的情况下访问libc等等…

通过使用0或NULL来表示文字值'\0'可能很诱人。 大多数C程序员都知道所有forms的NULL都可以工作。 在相关'\0'地方使用'\0'的优点是它是一种消除意图歧义的简洁方法。 '\0'代表一个角色 ,没有别的。