C语言核心内存操作:memcpy、memmove、memset与memcmp深度解析

小满
小满
发布时间:2026-10-16 | 5人浏览过
原创

C语言提供了强大的内存操作能力,其中 memcpy、memmove、memset 和 memcmp 是最常用的四个函数。理解它们的区别、底层实现原理及边界情况(如内存重叠),是编写高性能C程序的基础。

memcpy:基础内存拷贝

memcpy 用于从源地址 source 向目标地址 destination 复制 num 个字节的数据。其核心特性包括:

  • 无类型限制:基于 void* 指针操作,可拷贝任意数据类型(结构体、数组等)。
  • 不识别终止符:即使遇到字符串结束符 '\0' 也不会停止,严格按字节数复制。
  • 未定义行为:如果源和目标内存区域发生重叠,结果是不确定的。

第1步:理解 memcpy 的通用性

由于使用 void* 作为参数类型,memcpy 打破了字符串拷贝的限制。在实际操作中,通常将其强转为 char* 以进行逐字节操作。

/* num是几个字节的意思 */
void* my_memcpy(void* dest, const void* src, size_t num)
{
    assert(dest && src);
    void* ret = dest;
    while (num--)
    {
        // 和void*连用char*,分成最小然后一个一个传
        *(char*)dest = *(char*)src;
        ((char*)dest)++; // void*无类型不好直接加加,就强转char*再加加
        ((char*)src)++;
    }	
    return ret;
}

第2步:处理内存重叠问题

当源地址与目标地址存在交集时,简单的正向拷贝会导致数据被覆盖从而产生错误。

为解决此问题,C语言标准引入了 memmove。但在部分编译器(如Visual Studio)的实现中,memcpy 可能内部已优化为支持重叠拷贝,效果等同于 memmove。然而,为了保证代码的跨平台标准和严谨性,建议明确区分二者用途。

第3步:注意内存边界

若目标缓冲区空间不足,强行拷贝将导致程序崩溃或数据越界。

memmove:安全处理重叠拷贝

memmove 专门设计用于处理内存重叠场景。C语言规范明确指出:memcpy 仅保证非重叠拷贝,而 memmove 保证在所有情况下(含重叠)均能正确执行。

第4步:分析拷贝方向策略

解决重叠问题的关键在于确定拷贝方向:

  • 正向拷贝(dest < src):当目标地址在源地址之前时,可以从前往后拷贝,先处理低地址部分,不会影响尚未读取的高地址数据。
  • 反向拷贝(dest > src):当目标地址在源地址之后时,必须从后往前拷贝。先保存并写入高地址数据,防止前面的数据被新值覆盖。

第5步:memmove 源码实现

通过判断地址关系选择拷贝方向,确保数据的完整性。

/* num是几个字节的意思 */
void* my_memmove(void* dest, const void* src, size_t num)
{
    assert(dest && src);
    void* ret = dest;
    
    if (dest < src)
    {
        // 源内存从前向后拷贝
        while (num--)
        {
            *(char*)dest = *(char*)src;
            ((char*)dest)++;
            ((char*)src)++;
        }
    }
    else
    {
        // 源内存从后向前拷贝
        while (num--)
        {
            *((char*)dest+num) = *((char*)src+num);
        }
    }	
    return ret;
}

memset:内存初始化与设置

memset 用于将指定内存区域 dest 的前 num 个字节设置为指定的字符 value。常用于结构体清零或初始化数组。

memcmp:内存块比较

与 strcmp 类似,但操作对象是内存块而非字符串。memcmp 比较两个内存区域 buf1 和 buf2 的前 count 个字节。

分析:基本逻辑与字符串比较一致,即逐字节比对直到找到差异或达到指定长度。需注意 count 参数不要超出实际内存范围,因为内存操作没有自动补 '\0' 的机制。

第6步:memcmp 源码实现

// buf1内容比buf2大则返回 >0, 反之 <0
int my_memcmp(const void* buf1, const void* buf2, size_t count)
{
    assert(buf1 && buf2);
    while (--count && *(char*)buf1 == *(char*)buf2)
    {
        ((char*)buf1)++;
        ((char*)buf2)++;
    }
    if (*(char*)buf1 - *(char*)buf2 > 0)
        return 1;
    if (*(char*)buf1 - *(char*)buf2 < 0)
        return -1;
    return 0;
}

总结

掌握 memcpy 的高效性与 memmove 的安全性是C语言编程的关键。在处理内存重叠时必须使用 memmove;在进行大规模数据初始化时使用 memset;而在二进制数据对比时选用 memcmp。合理运用这些底层函数,能有效提升程序的健壮性与执行效率。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表