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

news2024/12/25 17:10:44

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.coloradmin.cn/o/1449755.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

姿态传感器MPU6050模块的姿态解算

姿态传感器 姿态传感器是基于MEMS技术的高性能三维运动姿态测量系统。它包含三轴陀螺仪、三轴加速度计,三轴电子罗盘等运动传感器,通过内嵌的低功耗ARM处理器得到经过温度补偿的三维姿态与方位等数据,比如角速度,加速度&#xff0…

微信小程序介绍、账号申请、开发者工具目录结构详解及小程序配置

目录 一、微信小程序介绍 1.什么是小程序? 2.小程序可以干什么? 3.微信小程序特点 二、账号申请 1.账号注册 2.测试号申请 三、安装开发工具 四、开发小程序 五、目录结构 JSON 配置 小程序配置 app.json 工具配置 project.config.json 页…

【Java】零基础蓝桥杯算法学习——动态规划例题

例题:2023年第十四届蓝桥杯Java软件开发B组E题 蜗牛 参考解答: 参考代码示例: import java.util.Scanner; public class Main {static int N 100010;static int[] arr new int[N];static int[] a new int[N]; //传送带的起始坐标static …

『 C++ - STL 』位图(BitMap)与布隆过滤器(Bloom Filter)

文章目录 🧸 位图(BitMap)概念🧸 位图的实现🪅 总体框架🪅 位图的数据插入🧩 左移操作与右移操作的区别 🪅 位图的数据删除🪅 位图的数据查找🪅 位图整体代码(供参考) 🧸…

Spring 事务原理总结五

很抱歉,Spring事务本来应该在上一篇就结束的,但因为梳理过程中发现了更多的未知知识,所以便再啰嗦几篇。本篇主要针对前一篇文章——《Spring 事务原理总结四》——末尾提到的几个问题进行梳理,这里再回顾一下这几个问题&#xff…

Maven 跳过单元测试

文章目录 方法一:命令行跳过执行测试用例方式二:命令行跳过编译与执行测试用例方式三:通过 POM 文件配置默认跳过测试方式四:IDEA 配置 VM OPtions 在软件开发过程中,Maven 自动化构建工具扮演着关键角色。尤其是&…

Nodejs 第三十七章(连表and子查询)

子查询 子查询(Subquery),也被称为嵌套查询(Nested Query),是指在一个查询语句中嵌套使用另一个完整的查询语句。子查询可以被视为一个查询的结果集,它可以作为外层查询的一部分,用…

【牛客面试必刷TOP101】Day21.BM11 链表相加(二)和BM12 单链表的排序

作者简介:大家好,我是未央; 博客首页:未央.303 系列专栏:牛客面试必刷TOP101 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!!&…

【微服务】skywalking自定义告警规则使用详解

目录 一、前言 二、SkyWalking告警功能介绍 2.1 SkyWalking告警是什么 2.2 为什么需要SkyWalking告警功能 2.2.1 及时发现系统异常 2.2.2 保障和提升系统稳定性 2.2.3 避免数据丢失 2.2.4 提高故障处理效率 三、 SkyWalking告警规则 3.1 SkyWalking告警规则配置 3.2 …

【Visual Studio】使用空格替换制表符

环境 VS版本:VS2013 问题 如何生成空格替换制表符? 步骤 1、菜单 工具->选项,文本编辑器->C/C->制表符,选择【插入空格】。

【数据结构】数组、双链表代码实现

💗💗💗欢迎来到我的博客,你将找到有关如何使用技术解决问题的文章,也会找到某个技术的学习路线。无论你是何种职业,我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章,也欢…

类和对象的内存分配机制

一、类和对象的内存分配机制 二、分配机制(总结) 三、内存图分析题

git stash 正确用法

目录 一、背景 二、使用 2.1 使用之前,先简单了解下 git stash 干了什么: 2.2 git stash 相关命令 2.3 使用流程 1. 执行 git stash 2. 查看刚才保存的工作进度 git stash list 3. 这时候在看分支已经是干净无修改的(改动都有暂存到 stash) 4. 现在…

数字的魅力之情有独钟的素数

情有独钟的素数 什么是素数 素数(Prime number)也称为质数,是指在非0自然数中,除了1与其本身之外不拥有其他因数的自然数。也就是说,素数需要满足两个条件: 大于1的整数;只拥有1和其自身两个…

LeetCode “AddressSanitizer:heat-use-after-free on address“问题解决方法

heat-use-after-free : 访问堆上已经被释放的内存地址 现象:同样代码在LeetCode上报错,但是自己在IDE手动打印并不会报错 个人猜测,这个bug可能来源于LeetCode后台输出打印链表的代码逻辑问题。 问题描述 题目来自LeetCode的8…

红队打靶练习:Alfa:1

下载连接点击此处即可! 目录 信息收集 1、arp 2、nmap 3、gobuster WEB web信息收集 FTP登录 smaba服务 crunch密码生成 提权 系统信息收集 权限提升 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, …

【C++航海王:追寻罗杰的编程之路】关于模板,你知道哪些?

目录 1 -> 泛型编程 2 -> 函数模板 2.1 -> 函数模板概念 2.2 -> 函数模板格式 2.3 -> 函数模板的原理 2.4 -> 函数模板的实例化 2.5 -> 函数参数的匹配原则 3 -> 类模板 3.1 -> 类模板的定义格式 3.2 -> 类模板的实例化 1 -> 泛型编…

深度学习疆界:探索基本原理与算法,揭秘应用力量,展望未来发展与智能交互的新纪元

目录 什么是深度学习 深度学习的基本原理和算法 深度学习的应用实例 深度学习的挑战和未来发展方向 挑战 未来发展方向 深度学习与机器学习的关系 深度学习与人类的智能交互 什么是深度学习 深度学习是一种基于神经网络的机器学习方法,旨在模仿人类大脑分析…

C语言学习day14:跳转语句

今天学习的跳转语句主要是三种: break continue goto 上一篇文章已经说过了break和continue break:结束这个循环 continue:结束当前的循环迭代,进行下一次的迭代 看看二者代码的区别 代码(break)&am…

php基础学习之文件包含

描述 在一个php脚本中,将另一个php文件包含进来,合作实现某种功能 这个描述看起来似乎和C/Java等语言的头文件/包有点类似,但本质是不一样的 打个比方: C/Java的头文件/包更像是一个工具箱,存放各种很完善的工具&#…