[C语言]memcpy和memmove图解

文章目录

1 memcpy

memcpy是操作内存的,其中以1byte的产生内存交换,和操作和strncpy相同且不再受任何类型限制。

void * memcpy ( void * destination, const void * source, size_t num );
  • memcpy不再受变量类型限制,且也不再受\0限制,转而和strncpy一样受到需要拷贝的数据长度限制。
  • 同样使用1byte作为操作单位,num值应该是 该类型所占用的字节 * 所需数据个数,例如:拷贝五个int数据 5 * 4 = 20 个字节
  • 需要保证目标空间有足额空间。
  • 需要使destination空间和soure空间不重叠
    在这里插入图片描述

arr2内容初始化为0,拷贝arr1中五个数据。

部分编译器使用memcpy操作重叠空间会出现的问题
![[memcpy1.gif]]

可以看到从目标地址开始数据出现了错误。
![[Pasted image 20231008205859.png]]

memcpy函数是从src指针指向的数据开始拷贝的,为什么数据会出现错误呢?
![[Pasted image 20231008210411.png]]

这是因为当拷贝过程中,src指向的数据覆盖了后续会指向的数据,使得数据最终拷贝出现错误。

2 memmove

memmove函数是专门用来处理destination空间和soure空间重叠的数据,也可以处理不同空间。

void * memmove ( void * destination, const void * source, size_t num );

为什么memmove操作重叠空间不会出错呢?
逐步分解memcpy操作步骤

memcpy(arr + 2, arr, 20);

![[Pasted image 20231008211624.png]]

当第一次发生拷贝时,arr[2]里的数据从 3 变成了 1,当函数需要拷贝arr[2]覆盖arr[4]这时拷贝的是1,而非原数据 3,
![[Pasted image 20231008212332.png]]

memmove就是可以避免这类问题的。

我们看看memmove处理逻辑
![[Pasted image 20231008213521.png]]

srcdest同时加上需要拷贝的数据长度,此时我们就从需要拷贝的数据的初始位置来到了末尾位置从末尾处开始拷贝,同时两指针同时根据拷贝完的数据逐步递减。
![[Pasted image 20231008214031.png]]

我们知道数组首元素地址是低于末尾位置地址的
所以我们可以举一反三,得出

  • dest地址大于src地址时,memmove函数处理是从需要拷贝的数据末尾开始往前拷贝
  • dest地址小于src地址时,memmove函数处理是从需要拷贝的数据初始位置往后拷贝

附:memcpymemmove模拟代码
memcpy

void * my_memcpy(void * dest,void * src,size_t sz){
    assert(dest && src);
    void * ret = dest;
    while (sz--)
    {
        *(char *)dest = *(char *)src;
        dest = (char *)dest+1;
        src = (char *)src+1;
    }
    return ret;
}

memmove

void * my_memmove(void * dest, void * src,size_t sz){
    assert(dest && src);
    void * ret = dest;
    if (dest < src)
    {
        while (sz--)
        {
            *(char *)dest = *(char *)src;
            dest = (char *)dest+1;
            src = (char *)src+1;
        }
        
    }else{
        while (sz--)
        {
            *((char *)dest + sz) = *((char *)src +sz);
        }
    }
    return ret;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值