库函数:memcpy 和 memmove

memcpy 和 memmove

都是C语言中的库函数,在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下:

void *memcpy(void *dst, const void *src, size_t count);

void *memmove(void *dst, const void *src, size_t count); 

他们的作用是一样的,唯一的区别是,当内存发生局部重叠的时候,memmove保证拷贝的结果是正确的,memcpy不保证拷贝的结果的正确。

举例说明

int arr[10] = {1,2,3,4,5,6,7,8,9,10}
当src指向1位置,dst指向3位置,当需要复制4个int也就是16个字节时,使用memcpy会造成覆盖问题。
原因:从前向后复制时,1会复制到3位置将还没拷贝的3覆盖为1。因此最后结果为:{1,2,1,2,1,2,7,8,9,10},而我们想要的结果为:{1,2,1,2,3,4,7,8,9,10}

  • 出现这种情况的原因就是我们从前向后复制会覆盖还未拷贝的信息,那么修改为从后向前复制即可。但是如果src在dst后面并且存在覆盖,从后向前也会造成覆盖问题。因此我们需要推导条件来选择复制方向。

当存在内存覆盖并且src(源地址)在dst(目标地址)之前,需要使用从后向前的拷贝。

if ((src < dst) && (char*)src + size > (char*)dst) //当然第二个条件可以不需要

具体实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
void* my_memcpy(void* dst, const void* src, size_t size) {
    char* psrc; //强转为了char会按照字节拷贝
    char* pdst;
    if (dst == nullptr || src == nullptr) {
        return nullptr;
    }
    //dst在src后面,并且拷贝区间和目标区间存在覆盖(覆盖前面内容),从后向前拷贝
    if ((src < dst) && (char*)src + size > (char*)dst) {
        psrc = (char*)src + size - 1;
        pdst = (char*)dst + size - 1;
        while (size--) {
            *pdst-- = *psrc--;
        }
    }
    else {
        psrc = (char*)src;
        pdst = (char*)dst;
        while (size--) {
            *pdst++ = *psrc++;
        }
    }

    return dst;
}

void* my_emmove(void* dst, const void* src, size_t cnt) {
    if (dst == nullptr || src == nullptr) {
        return nullptr;
    }
    char* dstp = (char*)dst;
    const char* srcp = (char*)src;
    
    if (src < dst) {
        dstp += cnt - 1;
        srcp += cnt - 1;
        while (cnt--) {
            *dstp-- = *srcp--;
        }
    }
    else {
        while (cnt--) {
            *dstp++ = *srcp++;
        }
    }
    return dstp;
}


int main(int argc, char* argv[])
{
    char buf[100] = "abcdefghijk";
    int arr[10] = { 1,2,3,4,5,6,7,8 };
    int arr1[10] = { 0 };
    //memcpy(buf+2, buf, 5);
    my_memcpy(arr + 2, arr, 16);
    printf("%s\n", buf);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值