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

实现memmove类似功能时遇编译错误,求问题分析与解决

ft_memmove实现问题排查与解答

编译错误原因

你遇到的error: lvalue required as increment operand错误和const数组无关,问题出在p++操作上:p是栈上变长数组的数组名,它本质是不可修改的左值(只读的指针常量),不能对它执行自增、自减这类修改操作。数组名在多数场景下会退化为指向数组首元素的指针,但它本身不是可修改的变量,因此不能用p++遍历数组。

memmove工作原理的确认

你对memmove的理解是正确的:man手册明确说明,memmove会先将源数据复制到一个不与目标地址重叠的临时区域,再将临时区域的数据复制到目标地址,以此避免源数据在复制过程中被覆盖(当源和目标地址重叠时)。

是否需要使用malloc?

当前用的栈上变长数组unsigned char p[n];在小数据量测试时没问题,但如果n的值很大,栈空间会被耗尽,导致栈溢出崩溃。所以更健壮的实现应该用malloc动态分配临时内存,用完后记得用free释放,避免内存泄漏。如果只是学习阶段做小范围测试,用变长数组也可以,但要注意数组的正确使用方式。

修正后的代码示例

方案1:用临时指针遍历栈上数组

把数组名赋值给一个可修改的指针变量,通过操作这个指针来遍历数组:

void    *ft_memmove(void *dest, const void *src, size_t n)
{
    unsigned char p[n];
    unsigned char *temp_p;
    unsigned char *p2;
    const unsigned char *p3;
    size_t i;

    p2 = (unsigned char *)dest;
    p3 = (const unsigned char *)src;
    temp_p = p;
    i = 0;
    // 先把源数据复制到临时数组
    while (i < n)
    {
        *(temp_p++) = *(p3++);
        i++;
    }
    // 重置临时指针到数组开头
    temp_p = p;
    // 把临时数组的数据复制到目标地址
    while (n--)
    {
        *(p2++) = *(temp_p++);
    }
    return (dest);
}

方案2:用malloc动态分配临时内存(更健壮)

避免栈溢出问题,同时处理边界情况:

void    *ft_memmove(void *dest, const void *src, size_t n)
{
    unsigned char *temp;
    unsigned char *p2;
    const unsigned char *p3;
    size_t i;

    // 边界情况:无需复制或源目标地址相同
    if (n == 0 || dest == src)
        return (dest);
    // 动态分配临时内存
    temp = (unsigned char *)malloc(n);
    if (!temp)
        return (NULL); // 内存分配失败返回NULL
    p2 = (unsigned char *)dest;
    p3 = (const unsigned char *)src;
    // 复制源数据到临时内存
    for (i = 0; i < n; i++)
        temp[i] = p3[i];
    // 复制临时内存数据到目标地址
    for (i = 0; i < n; i++)
        p2[i] = temp[i];
    // 释放临时内存
    free(temp);
    return (dest);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:02:36