【C语言】内存函数memcpy和memmove的功能与模拟实现

news/发布时间2024/5/15 7:43:28

1.memcpy

功能:把source指向的前num个字节内容拷贝到destination指向的位置去,可以拷贝任意类型的数据。

注:1.memcpy并不关心\0,毕竟传的也不一定是字符串,因此拷贝过程中遇到\0也不会停下来。

2.num的单位是字节,并不是要拷贝的元素个数

3.如果source和destination有任何的重叠,拷贝的结果都是未定义的。什么意思呢?举个例子,我现在要把arr1中的12345拷贝到34567的位置上去。

打印结果却并没有如愿,这是因为当我们把1拷贝到了3的位置上,2拷贝到了4的位置上,数组arr1的内容已经被改变了,当我们要拷贝3到5的位置上时,3已经变成了1,于是就把1拷贝过去了。于是出现了上图所示的情况。

也就是说memcpy只用于处理不重叠内存的数据。

模拟实现memcpy

像这种能够操作各种类型数据的函数,其底层实现原理基本上都和char*类型的指针有关系,比如memcpy,还有我们前面已经模拟实现过的库函数qsort。因为char*类型的指针走一步就跳过一个字节,字节又是内存单元的最小单位,不管是什么类型的数据,只要一个字节一个字节的操作,最终都可以达成目的。

因此在这里我们就把des和src两个指针强制类型转换成char*类型的,然后解引用对他们指向的那一个字节单元的内容进行赋值操作,赋值完一个字节之后再进行下一个字节单元的操作。注意强制类型转换只是一个临时的操作,并不是说我们在进行赋值的时候把des和src强制类型转换成char*类型的了,他就一直是char*类型的了,因此要让des和src指向下一个字节单元,应该写成des=(char*)des+1。

2.memmove

功能:也是拷贝内存数据

和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。如果源空间和目标空间出现重叠,就得使用memmove函数处理。

像刚才那个例子,我们就可以使用memmove解决

模拟实现memmove

思路:要在有重叠的数据里面实现拷贝,最大的问题就是在拷贝的过程中会改变原来位置的内容,第一想法是可以申请一块内存在里面存放原本数据的相同内容,这样当然可以,但是第一这种写法比较麻烦,第二会造成内存的浪费。能不能不申请内存就实现在同一块内存中拷贝内容呢?

当然可以,举个例子,12345678这串数字,现在我要把345处的内容拷贝成123,也就是最终让数字变成12123678,此时des在src的后面,如果我先把1拷贝到3的位置,那么后面在想把3拷贝到6处时就很尴尬,因为此时的3已经变成了1,但是如果我倒着拷贝,先把3拷贝到6的地方,再把2拷贝到5的地方,再把1拷贝到3的地方,不就行了吗?

再举一个例子,如果我要把345拷贝到123的位置,此时des在src的前面,我们直接把3拷贝到1的位置,4拷贝到2的位置,5拷贝到3的位置即可。

也就是说,如果dessrc,就从后往前拷贝。如果两块数据没有重叠,那从前或者从后都可以。

在代码中从后往前找的时候,先判断num是否为0,然后--,第一次的时候num是20,进入循环之后已经--了,变成了19,因此(char*)des + num与(char*)src + num都指向了最后一个要拷贝的位置。并随着num的减小不断指向前面位置。

注:memcpy能做的,memmove都能做。但是memmove能做的,memcpy不一定能做。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.bcls.cn/BAVm/13.shtml

如若内容造成侵权/违法违规/事实不符,请联系编程老四网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

turn服务器debug

turn服务器正常能连通的调用堆栈 turn_port.cc AddRequestAuthInfo check 崩溃 有问题的turn msg type是259 request type 是3 用不了的turn 服务器turnmessage type 275

【Django】Django文件上传

文件上传 1 定义&场景 定义&#xff1a;用户可以通过浏览器将图片等文件上传至网站。 场景&#xff1a; 用户上传头像。 上传流程性的文档[pdf&#xff0c;txt等] 2 上传规范-前端[html] 文件上传必须为POST提交方式 表单 <form> 中文件上传时必须带有 enctype…

你的电脑关机吗

目录 程序员为什么不喜欢关电脑&#xff1f; 电脑长时间不关机会怎样? 电脑卡顿 中度风险 硬件损耗 能源浪费 散热问题 软件问题 网络安全问题 程序员为什么不喜欢关电脑&#xff1f; 大部分人都会选择将电脑进行关机操作。其实这不难理解&#xff0c;毕竟人类都需要…

小白水平理解面试经典题目LeetCode 1025 Divisor Game【动态规划】

1025 除数游戏 小艾 和 小鲍 轮流玩游戏&#xff0c;小艾首先开始。 最初&#xff0c;黑板上有一个数字 n 。在每个玩家的回合中&#xff0c;该玩家做出的动作包括&#xff1a; 选择任意 x&#xff0c;使 0 < x < n 和 n % x 0 。将黑板上的数字 n 替换为 n - x 。 此…

【初始消息队列】消息队列的各种类型

消息队列相关概念 什么是消息队列 MQ(message queue)&#xff0c;从字面意思上看&#xff0c;本质是个队列&#xff0c;FIFO 先入先出&#xff0c;只不过队列中存放的内容是 message 而已&#xff0c;还是一种跨进程的通信机制&#xff0c;用于上下游传递消息。在互联网架构中…

idea:如何连接数据库

1、在idea中打开database: 2、点击 ‘’ ---> Data Source ---> MySQL 3、输入自己的账号和密码其他空白处可以不填&#xff0c;用户和密码可以在自己的mysql数据库中查看 4、最后选择自己需要用的数据库&#xff0c;点击运用ok&#xff0c;等待刷新即可 最后&#xff1a…
推荐文章