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

如何实现支持重叠区域的内存移动(memmove),现有代码错误如何排查?

内存移动(memmove)功能实现问题修复

原有代码存在的问题

  • 非法使用字符串终止符\0作为内存拷贝结束判断:内存块中可能包含数值为0的字节,且你需要拷贝固定size长度的内存,而非仅拷贝到字符串末尾,该判断逻辑完全不符合需求。
  • 临时缓冲数组逻辑错误:第一遍拷贝结束后指针b已经指向缓冲数组末尾,第二遍拷贝时读取的是缓冲数组外的非法内存数据,完全无法得到正确结果。
  • 变长数组char buff[size]存在安全风险:该写法属于C99可选特性兼容性差,且size过大时会直接触发栈溢出,使用临时缓冲的实现方案本身性能和可靠性都极低。
  • 未规范实现主函数:void main()不是C标准规定的主函数写法,标准实现应为int main(void)。

正确实现方案

不需要额外开辟缓冲,只需要根据源地址和目标地址的相对位置选择拷贝方向,即可完美处理重叠场景,代码如下:

#include <stdio.h>

void mem_move(void* dest, const void* src, unsigned size)
{
    // 转成char*按字节操作
    char* d = (char*)dest;
    const char* s = (const char*)src;
    
    if (d > s && d < s + size) {
        // 目标地址在源地址中间的重叠场景,从后往前拷贝
        d += size - 1;
        s += size - 1;
        while (size--) {
            *d-- = *s--;
        }
    } else {
        // 无重叠或者目标在源前面,正常从前往后拷贝
        while (size--) {
            *d++ = *s++;
        }
    }
}

int main(void)
{
    char buffer[] = "one two three  ";
    // 测试目标地址在源地址后面的重叠场景
    mem_move(buffer + 3, buffer, 10);
    printf("测试1结果:%s\n", buffer);

    char buffer2[] = "one two three  ";
    // 测试源地址在目标地址后面的重叠场景
    mem_move(buffer2, buffer2 + 3, 10);
    printf("测试2结果:%s\n", buffer2);
    return 0;
}

实现说明

  • 当目标地址位于源地址的内存区间内部时,从头部开始拷贝会覆盖还未读取的源数据,因此改为从尾部倒序拷贝即可避免该问题。
  • 不需要额外开辟内存空间,兼容性和性能都远优于临时缓冲方案。
  • 源指针加const修饰符合常量正确性要求,避免误修改源数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:06:04