You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何执行ft_strcpy后指针src及指向的数组c被修改?

问题分析:ft_strcpy执行后源数组被意外修改的原因

现象描述

执行dest = ft_strcpy(dest, src)后,指针src指向的数组c被修改,输出开头出现垃圾值;但直接通过write(1, ft_strcpy(dest, src), 10)打印函数结果时一切正常。经测试,当dest指向的数组c2长度小于c的长度+1时,就会触发源数组被修改的问题。

复现代码

char    *ft_strcpy(char *dest, char *src)
{
    char    *ptr1;
    char    *ptr2;

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


int main (void)
{
    char c[10] = "Hola Pepe ";
    char c2[10];
    char *src, *dest;
    src = c;
    dest = c2;

    write(1, src, 10);
    write(1, "\n", 1);
    write(1, dest, 10);
    write(1, "\n", 1);
    dest = ft_strcpy(dest, src);
    write(1, "----------\n", 11);
    write(1, src, 10);
    write(1, "\n", 1);
    write(1, dest, 10);
    //write(1, ft_strcpy(dest, src), 10);
}

问题根源

核心原因是缓冲区溢出(数组越界写入),破坏了相邻内存区域的数据:

  1. 源数组c[10]初始化的字符串"Hola Pepe "刚好占满10个字节,编译器无法自动添加字符串终止符\0。这导致ft_strcpy中的while (*src != '\0')循环无法正常终止,会持续读取src指向的内存,直到找到某个\0为止。
  2. 目标数组c2[10]长度同样为10,当ft_strcpy向c2写入10个字节后,会继续向c2之外的内存区域写入数据。由于栈上变量的布局特性,c数组很可能紧邻c2的内存区域,溢出的写入操作直接覆盖了c数组的内容,导致后续读取src时出现垃圾值。
  3. 直接调用write(1, ft_strcpy(dest, src), 10)时,write仅读取前10个字节就停止,此时c数组还未被完全覆盖,因此看起来结果正常;但执行赋值操作后再打印src,c已经被溢出数据破坏,就会显示垃圾值。

另外,ft_strcpy中的src = ptr1; dest = ptr2;属于冗余代码——函数参数是传值传递,修改函数内的src和dest副本不会影响外部指针,对逻辑无实际作用。

解决方案

  1. 确保源字符串有终止符:将源数组c的长度改为11,让编译器能在字符串末尾自动添加\0,比如:
    char c[11] = "Hola Pepe ";
    
  2. 保证目标缓冲区足够大:目标数组c2的长度必须能容纳源字符串的全部内容(包括\0),避免越界写入。如果源字符串长度为10(含\0),c2至少需要11个字节的空间。
  3. 可选:添加边界检查:如果需要更安全的实现,可以在ft_strcpy中加入目标缓冲区长度的参数,限制复制的字节数,避免无限制的越界写入。

内容的提问来源于stack exchange,提问作者NachoK66

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 13:24:55