memcpy内存拷贝函数
目录
一、memcpy内存拷贝函数
注意事项
二、memcpy与strcpy对比
三、模拟实现memcpy函数
四、memcpy函数不能进行两块存在内存重叠的空间的内存拷贝
五、改进my_memcpy函数
一、memcpy内存拷贝函数
头文件:string.h
函数原型:void* memcpy(void* destination , const void* source , size_t num)
函数作用:将源地址中num个字节的内容拷贝到目标地址中
参数分析:
void *是不指定具体类型指针,意味着该函数可以拷贝任意类型的数据
destination是目标地址,即将源地址的内容拷贝到目标地址中
source是源地址,为目标地址提供拷贝内容
num是拷贝多少个字节
实例代码1:两个数组空间的拷贝
char arr1[] = { 5,4,3,2,1 };
char arr2[] = { 1,2,3,4,5,6,7,8,9,10 };
memcpy(arr2, arr1, sizeof(arr1[0]) * 5);for (int i = 0; i < 10; i++)
{printf("%d ", arr2[i]);
}

实例代码2:destination和source不一定是数组,任意可读写的地址空间即可
char arr[20] = "abcdefg";
char* p = "123456789";
memcpy(arr + 2, p + 5, sizeof(char) * 4);printf("%s\n", arr);

注意事项:
1.拷贝时destination地址的空间需要足够大,至少大于等于num个字节
2.如果destination地址空间存在数据,将会被新数据覆盖
3.memcpy不能进行有内存重叠的两个地址的内存拷贝
二、memcpy与strcpy对比
memcpy是内存拷贝函数,strcpy是字符串拷贝函数
strcpy函数原型:char *strcpy(char *str1, const char *str2)
strcpy函数作用:将字符串str2中的内容拷贝到字符串str1中
对比memcpy函数:
1.memcpy函数逐字节拷贝,strcpy函数遍历str2时遇到\0即停止拷贝,并将\0也拷贝到str1中
2.memcpy函数可以拷贝任意类型数据,strcpy函数只能拷贝字符串
三、模拟实现memcpy函数
注意:优先级:后置++ > 强制类型转换,所以destination和source的强制类型转换需要加括号
void* my_memcpy(void* destination, const void* source, size_t num)
{if (destination == NULL || source == NULL){return NULL;}for (int i = 0; i < num; i++){*(char*)destination = *(char*)source;((char*)destination)++;((char*)source)++;}
}
实例代码:
char arr[] = "123456789";
memcpy(arr, arr + 5, 3);
printf("%s\n", arr);//678456789

四、memcpy函数不能进行两块存在内存重叠的空间的内存拷贝
VS改进后的memcpy函数可以进行内存重叠空间的拷贝:
C语言标准规定,memcpy函数不能进行两块有内存重叠的的空间的内存拷贝,但是在VS编译器下实际测试时,这是由于VS对memcpy函数进行了改进,使得其可以进行内存重叠的空间的拷贝。
char arr[] = "123456789";
memcpy(arr + 2, arr, 5);//121234589
printf("%s\n", arr);

模拟实现的my_memcpy函数不能进行内存重叠空间的拷贝:
但是当使用模拟实现的my_memcpy函数进行拷贝时,结果不尽人意……
结果并非预期的121234589,而是121212189
char arr[] = "123456789";my_memcpy(arr + 2, arr, 5);//121234589printf("%s\n", arr);

原因分析:
这是因为在进行内存重叠的两块空间拷贝时,会发生未拷贝的被已拷贝的数据覆盖
例如:将源空间的12345,拷贝到目标空间的34567
当1、2拷贝到3、4的位置时,数组变为121256789,源空间需要拷贝的3、4被1、2覆盖,无法进行拷贝,只能再将1、2拷贝到目标空间,显然这是错误的

五、改进my_memcpy函数
解决上述问题,需要改进的my_memcpy函数的算法
将拷贝的类型分为两类:1.源空间在目标空间前 2.目标空间在源空间前
1.源空间在目标空间前
如下图,常规方法从前向后拷贝(1~3,2~4,……),需要改进为从后向前拷贝(5~7,4~6,……),这样被覆盖的数据已经拷贝完了 ,不影响后续的拷贝

2.目标空间在源空间前
如下图,需要从前向后拷贝(3~1,4~2,……)

总体原则:第一次拷贝的空间不能覆盖源空间
改进后的my_memcpy函数:
void* my_memcpy(void* destination, const void* source, size_t num)
{if (destination == NULL || source == NULL){return NULL;}if (source < destination)//从后向前拷贝{for (int i = num - 1; i >= 0; i--){*((char*)destination + i) = *((char*)source + i);}}else//从前向后拷贝{for (int i = 0; i < num; i++){*(char*)destination = *(char*)source;((char*)destination)++;((char*)source)++;}}
}
测试代码:
char arr[] = "123456789";
my_memcpy(arr + 2, arr, 5);//121234589
printf("%s\n", arr);

相关文章:
memcpy内存拷贝函数
目录 一、memcpy内存拷贝函数 注意事项 二、memcpy与strcpy对比 三、模拟实现memcpy函数 四、memcpy函数不能进行两块存在内存重叠的空间的内存拷贝 五、改进my_memcpy函数 一、memcpy内存拷贝函数 头文件:string.h 函数原型:void* memcpy(void* …...
数组模拟堆
文章目录 QuestionIdeasCode Question 维护一个集合,初始时集合为空,支持如下几种操作: I x,插入一个数 x ; PM,输出当前集合中的最小值; DM,删除当前集合中的最小值(数…...
【深度学习基础知识(一):卷积神经网络CNN基础知识】
深度学习基础知识 深度学习基础知识(一):卷积神经网络CNN基础知识 卷积神经网络CNN基础知识 0、目录 1. CNN卷积神经网络的特点 2. 卷积操作基础知识 2.1 卷积操作的概念2.2 卷积操作的种类2.3 卷积操作后特征图谱大小计算公式 3. 池化操…...
Git使用入门
一、Git简介 Git 是一个开源的分布式版本控制系统。 Git版本控制的功能为保存不同版本的代码,保存代码的地方叫做仓库。 每个仓库中有多个分支,每个分支上又有很多节点,每个节点代表一个版本,不同的分支可以进行合并࿰…...
电机矢量控制算法和例程
电机矢量控制算法是一种高级的电机控制方法,它通过将电机转子空间矢量转换到旋转坐标系中,并在该坐标系中进行控制来实现对电机的精确控制。下面是对电机矢量控制算法的详细解释: 坐标系变换:电机矢量控制首先将电机转子空间矢量变…...
std::string_view概念原理及应用
概念 使用const string&作为参数是先使用字符串字面量编译器会创建一个临时字符串对象然后创建std::string。 或者一个函数提供char*和const string&参数的两个版本函数,不是优雅的解决方案。 于是需要一个只使用内存不维护内存的类。 原理 在visual s…...
lodash库_.chunk、_.pick、_.omit、_.cloneDeep、_.debounce方法
lodash 模块化、高性能的 JavaScript 实用工具库。官方文档:https://www.lodashjs.com 1.对数组进行分组 _.chunk(array, [size1]) 使用场景,如移动端页面一行能放5个元素,总共7条数据,将一维数组转为二维数组,让一个…...
Java使用FFmpeg对视频文件打标记
免安装 FFmpeg <dependency><groupId>ws.schild</groupId><artifactId>jave-all-deps</artifactId><version>3.0.1</version><exclusions><!-- 排除windows 32位系统 --><exclusion><groupId>ws.sch…...
Redux 学习笔记
在使用 React Redux 前,我们首先了解一下 Redux 的一些基础知识。 Redux 是 JavaScript 应用程序中用于状态管理的容器。它不依赖于任何框架,可以与任何 UI 库和框架一起使用。在应用程序中使用 Redux 时,Redux 是以可预测的方式管理状态。 …...
【Bug】8086汇编学习
文章目录 随笔Bug1、masm编译报错:Illegal use of register2、debug中使用段前缀3、[idata]在编译器中的处理4、push立即数报错5、报错:improper operand type6、程序莫名跳转到未知位置 (doing)7、DOSBox失去响应8、程序运行显示乱码9、程序运行导致DOS…...
JetBrains系列IDE全家桶激活
jetbrains全家桶 正版授权,这里有账号授权的渠道: https://www.mano100.cn/thread-1942-1-1.html 附加授权后的一张图片...
洛谷p1618三连击
import java.util.Scanner; //将 1-9 共9个数分成3组,分别组成3个三位数,且使这3个三位数构成A:B:C的比例,试求出所有满足条件的3个三位数。不满足输出“No!!!”。 public class Main {public static void main(String[] args) {Scanner sc …...
微信公众号h5写一个全局调用微信分享功能
1. 首先先安装依赖 npm install weixin-js-sdk --save 2. app.vue文件 <script> export default { onLaunch: function(e) {}, onShow: function(e) { console.log(App Show页面初始); // 路由参数存缓存的 这是为了防止他…...
聊聊精益需求的产生过程
这是鼎叔的第七十八篇原创文章。行业大牛和刚毕业的小白,都可以进来聊聊。 欢迎关注本公众号《敏捷测试转型》,星标收藏,大量原创思考文章陆续推出。本人新书《无测试组织-测试团队的敏捷转型》已出版ÿ…...
Linux - 还不懂 gdb 调试器?(调试软件)
前言 当前,我们可以使用 make/makefile 来程序化执行代码文件;可以使用 gcc/g 等编译器来编译代码;可以使用 vim 编辑器来编写代码;其实在 Linux 当中还有一个工具,可以实现调试工作,这个工具就是 -- gdb。…...
Linux:程序地址空间/虚拟地址等相关概念理解
文章目录 程序地址空间虚拟地址和物理地址地址的转换地址空间是什么? 程序地址空间 在C和C程序中,一直有一个观点是,程序中的各个变量等都会有一定的地址空间,因此才会有诸如取地址,通过地址访问等操作,那…...
Python之爬虫
目录 HTTP请求HTTP响应获得页面响应伪装用户访问打包数据爬取豆瓣top250 HTTP请求 HTTP:HypertextTransferProtcol 超文本传输协议 1、请求行 POST/user/info?new_usertrue HTTP/1.1#资源了路径user/info 查询参数new_usertrue 协议版本HTTP/1.1 2、请求头 Ho…...
打造自己的前端组件库(奶妈版,超详细)
打造自己的前端组件库 demo是开源的,自己上npm 或者 github 上都能搜到 新建vue项目(sass js vue2) vue create yt-ui 修改文件目录(如下) 修改: 1.src 更名 examples; 2. src/components移动到项目最外层;3.vue.config.js更改入口文件 /…...
6.调制阶数相关
1、调制阶数与峰均比的关系 调制阶数(modulation order)对峰均比(有一定的影响。 峰均比是用于衡量调制信号或波形在幅度上的动态范围的指标。它表示信号的最大峰值与平均功率之间的比值。较高的峰均比可能导致信号在传输或放大过程中出现过…...
Maven多模块管理(转载)
注意:父模块需设定打包方式为pom https://cloud.tencent.com/developer/article/1667275 dependencyManagement 统一管理子类依赖版本 在父类maven中加入,不会继承给子类,只能规定子类的依赖版本,子类加入dependence后无需写入 …...
如何用茉莉花插件3倍提升Zotero中文文献管理效率:终极指南
如何用茉莉花插件3倍提升Zotero中文文献管理效率:终极指南 【免费下载链接】jasminum A Zotero add-on to retrive CNKI meta data. 一个简单的Zotero 插件,用于识别中文元数据 项目地址: https://gitcode.com/gh_mirrors/ja/jasminum 还在为Zote…...
Windows Cleaner终极指南:5大核心功能彻底解决C盘爆红与系统卡顿问题
Windows Cleaner终极指南:5大核心功能彻底解决C盘爆红与系统卡顿问题 【免费下载链接】WindowsCleaner Windows Cleaner——专治C盘爆红及各种不服! 项目地址: https://gitcode.com/gh_mirrors/wi/WindowsCleaner Windows Cleaner是一款专为Windo…...
SteamCleaner终极指南:一键清理游戏缓存,轻松回收数十GB硬盘空间
SteamCleaner终极指南:一键清理游戏缓存,轻松回收数十GB硬盘空间 【免费下载链接】SteamCleaner :us: A PC utility for restoring disk space from various game clients like Origin, Steam, Uplay, Battle.net, GoG and Nexon :us: 项目地址: https…...
STM8S003F3P6串口通信避坑指南:为什么你的9600波特率总丢数据?
STM8S003F3P6串口通信避坑指南:为什么你的9600波特率总丢数据? 在嵌入式开发中,串口通信是最基础也最常用的功能之一。对于STM8S003F3P6这样的低成本MCU来说,串口通信看似简单,却隐藏着不少"坑"。很多开发者…...
3分钟快速上手:FigmaCN中文界面插件的终极指南
3分钟快速上手:FigmaCN中文界面插件的终极指南 【免费下载链接】figmaCN 中文 Figma 插件,设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 你是否曾在使用Figma时因为英文界面而感到困扰?面对"Frame&q…...
番茄小说下载器:三步解决你的离线阅读难题
番茄小说下载器:三步解决你的离线阅读难题 【免费下载链接】Tomato-Novel-Downloader 番茄小说下载器不精简版 项目地址: https://gitcode.com/gh_mirrors/to/Tomato-Novel-Downloader 还在为无法随时随地阅读番茄小说而烦恼吗?想要把心爱的小说保…...
三月七小助手:星穹铁道智能自动化解决方案,告别重复点击的终极指南
三月七小助手:星穹铁道智能自动化解决方案,告别重复点击的终极指南 【免费下载链接】March7thAssistant 崩坏:星穹铁道全自动 三月七小助手 项目地址: https://gitcode.com/gh_mirrors/ma/March7thAssistant 你是否厌倦了《崩坏&#…...
STP/RSTP/MSTP到底怎么选?一张图讲清华为/思科交换机防环协议演进与配置差异
STP/RSTP/MSTP技术选型指南:从协议原理到厂商配置实战 在网络架构设计中,环路预防是保障业务连续性的基石。当工程师面对STP、RSTP和MSTP三大生成树协议时,如何根据网络规模、业务需求和设备特性做出合理选择?本文将深入解析协议演…...
AD9361 LVDS接口时序详解:手把手教你搞定FPGA与射频收发器的数据对齐(附时序图分析)
AD9361 LVDS接口时序深度解析:从理论到实战的FPGA数据对齐指南 当射频工程师第一次将AD9361与FPGA平台对接时,往往会被LVDS接口的时序问题困扰——明明SPI配置正确,示波器上的差分信号也看似完美,但FPGA接收到的数据却总是出现错位…...
告别手动维护!用DataX-Web搞定MySQL到ClickHouse的增量同步(附时间戳配置)
基于DataX-Web的MySQL到ClickHouse增量同步实战指南 1. 数据同步的自动化革命 在数据驱动的时代,企业每天都要处理海量数据的流转与分析。传统的数据同步方式往往依赖手动脚本,不仅效率低下,还容易出错。我曾亲眼见证一家电商企业因为手动同步…...
