【问题标题】:Char *strcat Implementation leading to Segmentation FaultChar *strcat 实现导致分段错误
【发布时间】:2016-01-18 00:10:05
【问题描述】:
char *strcat(char*dest, char*src) {
    while (dest != '\0') {
        *dest++;
    }
    while (src != '\0') {
        *dest++ = *src++;
    }
    return dest;
}

我一直在*dest++ = *src++ 线上遇到分段错误。有关如何解决问题的任何想法?

【问题讨论】:

  • 您想检查destsrc 指向的值是否为空终止符,而不是指针本身。所以,while (*dest)while (*src)。还可以考虑将 src 设为指向 const 的指针,如下所示:const char* src
  • 除了@szczurcio提到的问题外,还需要对dest字符串进行NULL终止,同时保存dest的原始值,以便返回。
  • 为什么是-1?这可能不是正确的代码,但问题已明确定义,源示例格式良好。

标签: c strcat


【解决方案1】:

您的代码有 4 个问题:

  • 您正在比较指向空字符的指针,而不是比较它们指向的字符。由于在指针变为 0 之前需要将指针增加很多次,如果有的话,您正在读取和/或写入超出缓冲区的末尾,在此之前从/到无效内存,因此崩溃。李>
  • 您不要空终止目标字符串。
  • 您将指针返回到目标字符串的末尾,而不是原始目标字符串。这可能是一个有用的 API,但您应该为此使用不同的名称。
  • src 指针应声明为 const char * 以符合此函数的标准声明并允许将指向常量字符串的指针作为源传递。

这是一个更正的版本:

char *strcat(char *dest, const char *src) {
    char *saved = dest;
    while (*dest != '\0') {
        dest++;
    }
    while ((*dest++ = *src++) != '\0') {
        continue;
    }
    return saved;
}

【讨论】:

  • 这将返回作为dest传入的原始字符串,没有src连接
  • +1。添加第 4 个问题,dest 上可能的缓冲区溢出,因为没有检查 dest 是否有足够的分配内存。
  • @AlexanderPogrebnyak:这是 API 的一部分,没什么可抱怨的。调用者应该验证这一点,并确保 destsrc 都不是空指针。
  • @DarthVeder: strcat 应该返回它的第一个参数。是什么让您认为 src 没有串联?
  • 如果我打印结果,我会收到 dest @chqrlie
【解决方案2】:

好的:Kernighan 方式:

char *strcat(char *dest, char *src)
{
    char *org = dest;
    while(*dest++){;}
      // at this moment, *dest MUST be pointing to '\0'
    while(*dest++ = *src++){;}
      // at this moment, *dest MUST be pointing to '\0' agian
    return org;
}

更新(礼貌地@chqrlie):

char *strcat(char *dest, char *src)
{
    char *org = dest;
    for(; *dest; dest++) {;}
      // at this moment, dest MUST be pointing to '\0'
    while(*dest++ = *src++) {;}
      // at this moment, dest points past the '\0', but who cares?
    return org;
}

【讨论】:

  • 如果您使用推荐的谨慎标志进行编译,while(*dest++ = *src++) 会生成警告。这种组合的作业/测试,最好不要玩胆小鬼和括号。
  • -1 因为您复制了源字符串目标字符串的空终止符之后。如果*dest != '\0',则仅增加dest
  • 当代码有大bug的时候请不要这样吹嘘;-) C 编程是一种卑微的体验,如果你还没有使用-Wall,你还没有花足够的时间编程在 C 中。
  • 评论错误并不会删除它!在第一个循环之后,dest 指向 '\0'
  • 第一个循环之后,'\0'之后的dest点哪一部分你不明白?
【解决方案3】:

destsource 永远不会变成 '\0' 如果它们一开始不是空的(或者可能在很长一段时间后才正确,但你可能会在此之前很久就耗尽内存)。

你应该使用:

while(*dest != '\0'){
    dest++;
}
while(*src != '\0'){
   *dest++ = *src++;
}

检查指针下的值。

还有其他一些问题:

  • 结果字符串不是以空值结尾的。

  • 返回一个指向字符串结尾的指针。

正如其他人所说:src 也应该是 const pointer

应该这样做:

char *strcat(char *dest, const char *src)
{
    char *start_pos = dest;

    while(*dest != '\0')
        dest++;

    while(*src != '\0')
       *dest++ = *src++;

    *dest = '\0';
    return start_pos;
}

小细节:我会给这个函数取一个不同于标准使用的名称strcat()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 2020-10-05
    • 1970-01-01
    • 2013-02-04
    • 1970-01-01
    • 2011-02-23
    相关资源
    最近更新 更多