内存函数之memmove的模拟实现

C语言中的内存函数是对内存中数据实现更改操作的一系列函数,本文模拟实现memmove来分享一点对数据进行更改操作的一些较难点,还望各位大佬不吝赐教!

这里以int类型的数组为例,将数组内第5,6,7,8,9个元素向前移动到对应的第1,2,3,4,5个元素的位置并实现覆盖,即最后的数组内容应该是5,6,7,8,9,6,7,8,9,10,11,12,13,14,15。

原始数组 int arr1[15] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };

预计更改后 int arr1[15] = { 5,6,7,8,9,6,7,8,9,10,11,12,13,14,15 };

考虑的内存修改应该是能够对所有数据进行操作修改,因此设计函数my_memmove(void*dest,void*src,int byte)

void*表示可以接受任何类型的指针或地址

dest是移动到的目标的首个元素地址,src是你要移动对象的首个元素地址(分别对应上文中arr以及arr+4)

byte表示你要移动数据的字节,因为是int类型要移动5个数据的话应该是20个字节,因此应该传sizeof(int)*5给byte。

my_memmove(arr1+4, arr1, 5 * sizeof(int));

好了接下来是函数具体的实现,先看目前指针的位置

显然只要把src处的元素放到dest处,然后执行dest++和src++再将新的src处元素放到新的dest处,只到5个元素都移动成功即可

考虑到void*类型的指针不能直接解引用,因此先转换为char*类型再进行更改操作。

为什么转换为char*?因为char*类型的指针加1只移动一个字节,可以较好的操作其他类型数据的内存。

这样一来上述修改内存和指针移动只需进行byte次(byte为你要移动的数据所占的内存)

void my_memmove(void* dest, void* src, int byte)

{

for (; byte > 0; byte--)

{

*(char*)dest = *(char*)src;

dest = (char*)dest + 1;

src = (char*)src + 1;

}

}

最后用for循环打印数组内容

完了吗?没完,按照上述方法只能让dest指针在src指针左边或重合的情况完成预期任务,若src在dest左边就会出错,将arr1和arr1+4交换位置

my_memmove(arr1+4, arr1, 5 * sizeof(int));

理论上数组内容应该是1,2,3,4,1,2,3,4,5,10,11,12,13,14,15

实际上是1,2,3,4,1,2,3,4,1,10,11,12,13,14,15

图解一下

好了第五次移动即将出问题

没错,理论上此刻dest部分应该从9修改为5,但是实际上确实9修改为1

这是因为此刻src指向的元素不是原始数组中的5,而是被修改成为了1

因此造成了修改错误

所以,面对src在dest左边的情况下我们有必要使用另一种方法来移动数据

我们可以从后开始移起,就是让可能提前被覆盖的数据先移,这样避免了出错。

因此这样就得到了最终函数的代码

void my_memmove(void* dest, void* src, int byte)

{

if(src>=dest)

for (; byte > 0; byte--)

{

*(char*)dest = *(char*)src;

dest = (char*)dest + 1;

src = (char*)src + 1;

}

else

for (;byte>0;byte--)

{

*((char*)dest + byte-1) = *((char*)src + byte-1);

}

}

图解

需要注意的是byte自减4次才表现为上图指针移动1格(因为char*类型指针移动4次等于int*类型指针移动1次)

进行byte次操作即可实现数据移动

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值