memmove和memcpy函数

所需头文件

#include<string.h>

一、memcpy函数

 1、功能

从源内存块拷贝非重叠的数据到目标内存块

2、核心特点与行为

(1) 非重叠假定:memcpy 的实现假定源内存区域 (src) 和目标内存区域 (dest) 绝对不会重叠。
(2) 未定义行为 :如果 src 和 dest 的内存区域存在任何形式的重叠,其行为是未定义的。这意味着程序可能会崩溃、产生错误数据,或者看似正常工作。
(3) 实现:通常是从前向后(低地址到高地址)进行拷贝,因为它不需要考虑重叠问题,实现简单高效。

3、示例

#include <stdio.h>
#include <string.h>

int main() {
    char src[] = "Hello, World!";
    char dest[20];

    // 安全的使用场景:拷贝两个独立不重叠的内存块
    memcpy(dest, src, strlen(src) + 1); // +1 是为了拷贝字符串结束符 '\0'
    printf("dest: %s\n", dest); // 输出: Hello, World!

    // 危险的使用场景:重叠拷贝 
    char data[] = "ABCDEFG";
    memcpy(data + 2, data, 5); // 将"ABCDE"拷贝到"CDEFG"的位置
    printf("data: %s\n", data); // 输出结果不可预测,可能是 "ABABABA" 等

    return 0;
}

二、memmove函数

1、功能

从源内存块拷贝任何数据(包括重叠)到目标内存块

2、核心特点与行为

 重叠安全:memmove 会检查 src 和 dest 的位置关系,并自动选择正确的拷贝策略来保证结果的正确性。
策略:
  (1) 如果 dest < src (目标在源前面):采用从前向后(低地址到高地址)拷贝。这样可以防止覆盖源区中尚未被拷贝的数据。
  (2) 如果 dest > src (目标在源后面):采用从后向前(高地址到低地址)拷贝。这样可以防止覆盖源区中尚未被拷贝的数据。
  (3) 如果区域不重叠:任何一种策略都可以,结果与 memcpy 完全相同。

3、示例

#include <stdio.h>
#include <string.h>

int main() {
    // 1: 目标地址在源地址之后 (重叠)
    char str1[] = "ABCDEFG";
    printf("Before memmove (overlap, dest > src): %s\n", str1);
    memmove(str1 + 2, str1, 5); // 将 "ABCDE" 移动到 "CDEFG" 的位置
    printf("After memmove: %s\n", str1); // 正确输出: ABABCDE

    // 2: 目标地址在源地址之前 (重叠)
    char str2[] = "ABCDEFG";
    printf("Before memmove (overlap, dest < src): %s\n", str2);
    memmove(str2, str2 + 2, 5); // 将 "CDEFG" 移动到 "ABCDE" 的位置
    printf("After memmove: %s\n", str2); // 正确输出: CDEFGFG

    // 3: 完全不重叠 (行为与memcpy一致)
    char src[] = "Hello";
    char dest[10];
    memmove(dest, src, 6); // 拷贝5个字符+'\0'
    printf("No overlap: %s\n", dest); // 输出: Hello

    return 0;
}

注意:在vs中两种函数对待含有重叠部分的拷贝行为,结果相同均正确,原因是vs对其做出了超出c标准的扩展实现,与函数本身无关。

总结:推荐使用更安全,更通用的memmove函数

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值