内存函数 memcpy 和 memmove 的讲解和模拟实现

news2024/11/22 19:49:47

目录

一.什么是 memcpy 函数

模拟思路

代码实现 

二.什么是 memmove 函数

模拟思路

代码实现


一.什么是 memcpy 函数

我们打开 cplusplus 官网查看:

memcpy - C++ Reference (cplusplus.com)

官方文本显示:

内存复制块

  • 将 num 字节的值从源指向的位置直接复制到目标指向的内存块
  • 源指针和目标指针所指向的对象的底层类型与此函数无关;结果是数据的二进制副本
  • 该函数不检查源中是否有任何终止null字符——它总是精确地复制num个字节
  • 为了避免溢出,目标参数和源参数所指向的数组的大小应该至少为 num 字节,并且不应该重叠(对于重叠的内存块,memmove 是一种更安全的方法)

上述文本可能不够直观,我们使用官方提供的例子观察他的具体作用:

/* memcpy example */
#include <stdio.h>
#include <string.h>

struct 
{
	char name[40];
	int age;
} person, person_copy;

int main()
{
	char myname[] = "Pierre de Fermat";

	/* using memcpy to copy string: */
	memcpy(person.name, myname, strlen(myname) + 1);
	person.age = 46;

	/* using memcpy to copy structure: */
	memcpy(&person_copy, &person, sizeof(person));

	printf("person_copy: %s, %d \n", person_copy.name, person_copy.age);

	return 0;
}

 输出结果:

        结合代码和输出结果来看,我们申明了俩个结构体,并且我们手动给结构体 person 的俩个变量进行了赋值,而结构体 person_copy 我们并没有对其初始化赋值,我们使用了 memcpy 函数将结构体 person 中的值复制给了结构体 person_copy ,然后我们打印输出 person_copy 中的变量的值,发现我们确实是拿到了这俩个值

模拟思路

当我们拿到一个字符串后,首先要确定复制的起点位置和复制目标的起点位置

 

然后逐一复制字节

 

代码实现 

        在这里,我们使用 void* 的指针来拿到各种数据类型的地址,然后强制转化为 char* 方便我们对单个字节进行访问(字符型指针解引用只能访问一个字节),函数参数方面,只需要拿到俩个地址加上需要复制多少个字节的大小的值就可以了

void* my_memcpy(void* dest, const void* src, size_t sz)
{
	void* ret = dest;
	assert(dest && src);
	while (sz--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

二.什么是 memmove 函数

我们打开 cplusplus 官网查看:

memmove - C++ Reference (cplusplus.com)

 

官方文本显示:

移动内存块

  • 将 num 字节的值从源指向的位置复制到目标指向的内存块。复制就像使用了中间缓冲区一样进行,从而允许目标和源重叠
  • 源指针和目标指针所指向的对象的底层类型与此函数无关;结果是数据的二进制副本
  • 该函数不检查源中是否有任何终止 null 字符——它总是精确地复制 num 个字节
  • 为了避免溢出,目的参数和源参数所指向的数组的大小至少为 num 字节

上述文本可能不够直观,我们使用官方提供的例子观察他的具体作用:

 

/* memmove example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] = "memmove can be very useful......";
  memmove (str+20,str+15,11);
  puts (str);

  return 0;
}

输出结果:

        我们可以看见,原本的字符串是 memmove can be very useful...... 但是输出的却是 memmove can be very useful. 也就是我们将后半部分的 very useful 往后移动了一段距离

模拟思路

        在模拟实现这个功能之前,有一点值得注意,相较于之前的 memcpy 函数,这里的 memmove 函数在移动的时候,内部是有重复部分的,如果还是按照上面那种方法实现的话,会出现数据反复覆盖导致丢弃了真实数据的情况,如图所示

对于这个情况,我们换一个交换字节的顺序就可以解决,如图

        也就是说,我们只需要做出合理的判断,选择正确的顺序,就可以实现功能,根据我们的经验,如果我们要实现的是从前往后移动拷贝的话,那我们就从后往前访问,反之,如果我们要从后往前移动拷贝的话,那我们就从前往后访问

代码实现

void* my_memmove(void* dest, const void* src, size_t sz)
{
	assert(dest && src);
	void* ret = dest;
	if (dest < src)
	{
		//前->后
		int i = 0;
		for (i = 0; i < sz; i++)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		//后->前
		while (sz--)
		{
			*((char*)dest+sz) = *((char*)src + sz);
		}
	}
	return ret;
}

本次分享就到此为止了,如有错误欢迎积极指出,希望我的分享能给您带来帮助

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

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

相关文章

怎样防止员工泄露技术?(十条避免公司泄密的措施)

在当今信息化社会&#xff0c;公司信息的安全性和保密性显得尤为重要。一旦公司信息泄露&#xff0c;不仅会对公司的经营造成严重影响&#xff0c;还可能引发法律纠纷。因此&#xff0c;采取有效的措施来防止公司信息泄露是非常必要的。以下是一些具体的措施&#xff1a; 部署洞…

makedown语法及相关语法格式

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

Linux学习记录——삼십 socket编程---udp套接字

文章目录 UDP套接字简单通信1、服务端1、创建文件&#xff0c;写框架2、用命令行参数调起程序3、服务端运行逻辑 2、客户端1、创建套接字2、发送数据 3、测试4、通信5、加功能1、处理数据2、群聊 6、Windows下socket编程的不同 UDP套接字简单通信 1、服务端 1、创建文件&…

手动部署 OceanBase 集群

手动部署一个 OB 单副本集群&#xff0c;包括一个 OBProxy 节点 部署环境 服务器信息 IP地址 192.168.0.26 网卡名 ifcfg-enp1s0 OS Kylin Linux Advanced Server release V10 CPU 8C 内存 32G 磁盘1 本地盘 /data/1 磁盘2 本地盘 /data/log1 机器和角色划分 …

Python之使用PySimpleGUI打造桌面应用

PySimpleGUI 是一款比较新的, 基于Python实现的GUI图形库, 他桌面的布局方式采用的是列表方式实现的. Github 仓库地址: github.com/PySimpleGUI… 安装 使用 pip 工具安装即可 shell 复制代码 pip install PySimpleGUI简单的交互 代码 py 复制代码 import PySimpleGUI as …

LeetCode 416.分割等和子集(动态规划【0-1背包问题】采用一维数组dp:滚动数组)

>>往期文章&#xff1a; 解决0-1背包问题&#xff08;方案一&#xff09;:二维dp数组_呵呵哒(&#xffe3;▽&#xffe3;)"的博客-CSDN博客 解决0-1背包问题&#xff08;方案二&#xff09;&#xff1a;一维dp数组&#xff08;滚动数组&#xff09;_呵呵哒(&…

【前端】零基础快速搞定JavaScript核心知识点

【前端】零基础快速搞定JavaScript核心知识点 1.初识JavaScript 1.1.JavaScript语言简介 &#xff08;1&#xff09;简介 JavaScript 是互联网上最流行的脚本语言&#xff0c;这门语言可用于 HTML 和 web&#xff0c;更可广泛用于服务器、PC、笔记本电脑、平板电脑和智能手机…

OpenCV直方图的原理与显示、掩膜、均衡化、自适应均衡化

直方图 1 灰度直方图 1.1直方图的绘制和计算 代码实现 import numpy as np import cv2 as cv import matplotlib.pyplot as plt#直接以灰度图的方式读入img cv.imread("lena.png",0)#统计灰度图 histr cv.calcHist([img],[0],None,[256],[0,256]) 使用 OpenCV 的 c…

list容器排序案例

案例描述:将Perspn自定义数据类型进行排序&#xff0c;Person中属性有姓名、年龄、身高 排序规则:按照年龄进行升序&#xff0c;如果年龄相同按照身高进行降序 代码示例 #include <iostream> #include <string.h> #include <iterator> #include <vector…

java-- 字符串+拼接详解, 性能调优 (底层原理实现)

目录 简单了解一下字符串 String类里面是如何存放字符串的? String的不可变性 字符串拼接的方法 1.使用拼接字符串 2. 使用concat 3. 使用StringBuilder 4.StringBuffer 使用字符串拼接的原理 使用concat StringBuilder 效率比较 简单了解一下字符串 字符串在java…

Flink---5、聚合算子、用户自定义函数、物理分区算子、分流、合流

星光下的赶路人star的个人主页 欲买桂花同载酒&#xff0c;终不似&#xff0c;少年游 文章目录 1、 聚合算子1.1 按键分区&#xff08;KeyBy&#xff09;1.2 简单聚合&#xff08;Sum/Min/MinBy/MaxBy&#xff09;1.3 归约聚合&#xff08;Reduce&#xff09; 2、用户自定义函数…

redis实战-实现笔记点赞和点赞排行榜

发布探店笔记 探店笔记类似点评网站的评价&#xff0c;往往是图文结合。对应的表有两个&#xff1a; tb_blog&#xff1a;探店笔记表&#xff0c;包含笔记中的标题、文字、图片等 tb_blog_comments&#xff1a;其他用户对探店笔记的评价 保存笔记service层 Overridepublic Re…

实例讲解Spring boot动态切换数据源

前言 在公司的系统里&#xff0c;由于数据量较大&#xff0c;所以配置了多个数据源&#xff0c;它会根据用户所在的地区去查询那一个数据库&#xff0c;这样就产生了动态切换数据源的场景。 今天&#xff0c;就模拟一下在主库查询订单信息查询不到的时候&#xff0c;切换数据…

什么是UWB定位技术?UWB定位的应用场景及功能介绍

说到定位我们并不陌生&#xff0c;定位技术一直与我们的生活密不可分&#xff0c;比如最常见的车辆导航。 根据使用场景&#xff0c;定位技术分为室内定位和室外定位。 室外定位主要依靠GPS&#xff0c;北斗&#xff0c;GLONASS&#xff0c;伽利略等全球卫星定位导航系统。室内…

系统集成|第十一章(笔记)

目录 第十一章 项目人力资源管理11.1 项目人力资源管理的定义及有关概念11.2 主要过程11.2.1 编制项目人力资源管理计划11.2.2 组建项目团队11.2.3 建设项目团队11.2.4 管理项目团队 11.3 现代激励理论11.4 项目经理所需具备的影响力11.5 常见问题 上篇&#xff1a;第十章、质量…

有效保护敏感数据的最佳实践

在当今数据驱动的环境中&#xff0c;数据就是力量&#xff0c;组织仍然高度关注如何利用其数据进行 BI、分析和其他业务驱动计划。 事实上&#xff0c;最近的研究表明&#xff0c;数据领导者的主要动机是对高质量分析洞察的需求&#xff0c;而不是合规性。 然而&#xff0c;…

八大排序--------(五)堆排序

本专栏内容为&#xff1a;八大排序汇总 通过本专栏的深入学习&#xff0c;你可以了解并掌握八大排序以及相关的排序算法。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;八大排序汇总 &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库…

如何防止商业秘密泄露(洞察眼MIT系统商业机密防泄密解决方案)

在当今的商业环境中&#xff0c;保护公司的商业秘密是至关重要的。商业秘密可能包括独特的业务流程、客户列表、研发成果、市场策略等&#xff0c;这些都是公司的核心竞争力。一旦这些信息被泄露&#xff0c;可能会对公司的生存和发展产生重大影响。本文将探讨如何通过使用洞察…

【数据结构--排序】堆排序

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

Java 项目-基于 SpringBoot+Vue的疫情网课管理系统

文章目录 第一章 简介第二章 技术栈第三章 系统分析3.4.2学生用例 第四章 系统设计第五章 系统实现5.1学生功能模块5.2管理员功能模块5.3教师功能模块 六 源码咨询 第一章 简介 疫情网课也都将通过计算机进行整体智能化操作&#xff0c;实现的功能如下。 例如 管理员&#x…