【问题标题】:Implementation of strdup() in C programmingC语言中strdup()的实现
【发布时间】:2016-05-10 08:02:23
【问题描述】:

我正在努力在 C 中实现 strdup(),我是 C 新手,我正在尝试构建自己的库。我正在使用来自string.h 的实际strdup() 来测试我的,当我针对主程序测试我的源代码时遇到了总线错误,但当我使用实际的strdup() 时却没有。我也不能使用除malloc()之外的任何现有功能。

源代码:

#include <stdlib.h>

char *ft_strdup(char *src)
{

    char *str;
    int len;

    while (src[len])
        len++;
    str = (char*)malloc(sizeof(*str) * (len+1));
    while (*src)
        *str++ = *src++;
    *str = '\0';
    return (str);
}

为什么我总是收到总线错误?

【问题讨论】:

  • 你错过了用0初始化len
  • 我是 C 新手,我正在尝试构建自己的库——通常不是一个好主意。在I started my own standard library 之前,我已经使用 C 多年了,多年后我仍然在使用它。 &lt;string.h&gt; 函数一般来说很简单,但是你会很快遇到问题(或者太天真地实现这些函数,让你的项目崩溃得令人沮丧)。第一步,在标准库的用户端尝试一些东西。
  • @user3121023 谢谢,如何将指针返回到开头?
  • @user3121023 没关系,感谢我破解它的一切。
  • strdup() 不是标准库的一部分,因此在某些情况下(例如将依赖它的代码移植到其他系统),您需要自己实现。

标签: c


【解决方案1】:

尝试以下修复:

  1. 在递增之前初始化len
  2. Don't cast malloc's return value,不要使用sizeof(char),它在标准中被定义为1,每个cstd 6.5.3.4p4:

    当 sizeof 应用于类型为 char、unsigned char 或 带符号的字符,(或其合格版本)结果为 1。

  3. 使用指针保存原来的str指针

#include <stdlib.h>

char *ft_strdup(char *src)
{
    char *str;
    char *p;
    int len = 0;

    while (src[len])
        len++;
    str = malloc(len + 1);
    p = str;
    while (*src)
        *p++ = *src++;
    *p = '\0';
    return str;
}

【讨论】:

  • 你能解释一下第2点吗?关于 malloc 的铸造和 sizeof 的使用?
  • @afullstopdot 当然,出于第 2 点的原因,我已经更新了帖子。
  • 一个小时前我真的开始使用stackoverflow,我不知道我能做到这一点。 @machine_1。我现在会的。
  • 请注意,*p++ = *src++ 等价于 *(p++) = *(src++),因为后缀运算符 ++ 的优先级高于取消引用运算符 *
【解决方案2】:

如果您必须实现自己的 strdup 函数,至少尽可能多地依赖 string.h 的其余部分。其中许多函数都经过优化,速度比您自己编写的要快。例如,strlen 可能正在使用 SSE 指令,而您手动搜索空终止符字节却不是。它的代码也更少,这总是更好。简而言之,我建议这样做:

#include <stdlib.h>
#include <string.h>

char *ft_strdup(const char *s1)
{
  char *str;
  size_t size = strlen(s1) + 1;

  str = malloc(size);
  if (str) {
    memcpy(str, s1, size);
  }
  return str;
}

【讨论】:

  • 您忘记对字符串进行空终止。 str[len] = '\0'。请编辑您的帖子并更正此问题。
  • char *ft_strdup(const char *str) { return strcpy(malloc(strlen(src)+1), str); } ;-)
  • 当然,你和我的操作函数的语义都有错误,因为真正的strdup()在分配错误时返回NULL,而不是segmentation fault
  • @Lundin:实际上,我应该在 memcpy 中复制空终止符。一个简单的 + 1 就可以了。
猜你喜欢
  • 2012-06-07
  • 2011-05-09
  • 2013-11-25
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-24
  • 2023-03-07
相关资源
最近更新 更多