memcpy与memmove函数的区别和实现

2023-05-16

1.函数定义

memcpy与memmove都是C语言的库函数,在头文件string.h中,作用是内存拷贝。唯一的区别是,当内存发生局部重叠时,memmove保证了拷贝的结果是正确的,但是memcopy不一定是正确的。但是memcpy比memmove速度快。

void * memcpy ( void * destination, const void * source, size_t num );
void * memmove ( void * destination, const void * source, size_t num );

destination即目标空间,即要复制到哪个空间
source即源空间,即要被复制的内存空间
num即要复制多少个字节的内容到destination
void*即返回目标空间

 这是对memcpy和memmove函数的声明,可以明确看出,其返回的是void*类型的指针,并且有三个参数,第一个参数表示目标地址,第二个参数表示源地址,第三个参数表示拷贝大小(单位是字节)。此函数代表着,在内存空间中,从source指向的空间开始,往后一共num个字节的内存空间,将这些空间里面的内容拷贝到 从destination指向的空间开始,往后一共num个字节的内存空间。
 

2.memcpy代码实现

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

3.memmove代码实现

void* my_memmove(void* dest, const void* src, size_t count) {
	assert(dest && src);
	void* ret = dest;
	if (dest < src) {
		while (count--) {
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else {
		dest = (char*)dest + count - 1;
		src = (char*)src + count - 1;
		while (count--) {
			*(char*)dest = *(char*)src;
			dest = (char*)dest - 1;
			src = (char*)src - 1;
		}
	}
	return ret;
}

4.内存拷贝原则

首先将void*强制转换成char*;其次一个字节一个字节拷贝内存;然后指向目标空间和源空间地址的指针每次往后走一个字节的位置,循环拷贝相应的字节数即可。

5.拷贝情况分类

1)两块不同的内存,memcpy和memmove拷贝结果一致。

2)内存重叠,分为两种情况。如下图所示:

 代码验证三种情况如下:

#include <stdio.h>
#include <string.h>
int main()
{
	char szdes[40];
	char szsrc[] = "Pierre de Fermat";

	memcpy(szdes, szsrc, strlen(szsrc) + 1);//+1是因为要拷贝\0
	printf("%s\n",szdes);

	int arr1[10] = {0};
	int arr2[5] = {4,2,55,88,3};
	memcpy(arr1+3, arr2, sizeof(arr2));  //arr1是 arr1[10]这个数组首元素的地址,+3就是跳过3个int类型的数据
	for (int i = 0;i < 10;i++)
		printf("%d, ", arr1[i]);
	printf("\n");

	int arr3[10] = {1,2,3,4,5,6,7,8,9,10};
	memcpy(arr3, arr3+2, 5*sizeof(int));
	for (int i = 0;i < 10;i++)
		printf("%d, ", arr3[i]);
	printf("\n");

	int arr4[10] = {1,2,3,4,5,6,7,8,9,10};
	memmove(arr4, arr4+2, 5*sizeof(int));
	for (int i = 0;i < 10;i++)
		printf("%d, ", arr4[i]);
	printf("\n");

	int arr5[10] = {1,2,3,4,5,6,7,8,9,10};
	memcpy(arr5+2, arr5, 5*sizeof(int));
	for (int i = 0;i < 10;i++)
		printf("%d, ", arr5[i]);
	printf("\n");

	int arr6[10] = {1,2,3,4,5,6,7,8,9,10};
	memmove(arr6+2, arr6, 5*sizeof(int));
	for (int i = 0;i < 10;i++)
		printf("%d, ", arr6[i]);
	printf("\n");

	return 0;
}

window上vs输出结果为:

 linux 输出结果为:

6.总结

1)szsrc拷贝到szdes 上(arr2拷贝到arr1上),由于两块不同的内存块,memcpy和memmove功能一样,拷贝正确。

2)arr3和arr4,由于dest的指针地址在src的地址前面,且拷贝是一个字节一个字节的拷贝,虽然有局部内存重叠,但是按照从前往后拷贝的原则,其覆盖内容是旧空间的内容,memcpy和mommove的拷贝都是正确的。

3)arr5和arr6,由于dest的指针地址在src的地址后面,这种情况下,memcpy拷贝可能会存在错误,memmove拷贝正确。如上两图的输出结果可以看出,相同代码在不同环境下,其数据的内容不一致。此种拷贝linux的运行结果错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

memcpy与memmove函数的区别和实现 的相关文章

  • 遇见AI,从Java到数据挖掘。

    在上小学的时候就听说过AI xff0c 人工智能 xff0c 那个时候我对人工智能的感受都来自于各类影视作品 xff0c 类人的外表 xff0c 能听说读写 xff0c 有情感 xff0c 会思考 所以那个时候的我将人工智能想象成和人类相似
  • PyTorch模型保存与加载

    torch save xff1a 保存序列化的对象到磁盘 xff0c 使用了Python的pickle进行序列化 xff0c 模型 张量 所有对象的字典 torch load xff1a 使用了pickle的unpacking将pickle
  • ROS和ROS2.0到底该用哪个呢?

    很多朋友经常问ROS1 0 下文简称ROS 和ROS2 0我到底该学习 使用哪个呢 欢迎拍砖讨论 但若是因此对您的项目或产品造成了损失 本人不负任何责任 我先给出个人的观点 再说明其中原因 对于大众学习者 普通开发者 机器人算法开发者 在2
  • C++ Primer第五版_第一章习题答案

    文章目录 题目概览1 1 编译器文档1 2 错误标识1 3 Hello World1 4 两数相乘1 5 独立语句1 6 程序合法性1 7 不正确的嵌套注释1 8 语句合法性1 9 50到100的整数相加1 10 递减顺序打印10到0之间的
  • C++ Primer第五版_第十五章习题答案(11~20)

    文章目录 练习15 11练习15 12练习15 13练习15 14练习15 15Disc quote hBulk quote h 练习15 16练习15 17练习15 18练习15 19练习15 20 练习15 11 为你的 Quote 类
  • ROS机器人操作系统(roscpp)

    1 Client Library与roscpp 1 1 Client Library简介 ROS为机器人开发者们提供了不同语言的编程接口 比如C 接口叫做roscpp Python接口叫做rospy Java接口叫做rosjava 尽管语言
  • OpenCVSharp之ArucoSample例程

    ArUco xff1a 是一个根据预设黑白Markers来估计相机位姿的开源库 该库由C 43 43 编写 xff0c 运行速度很快 已被应用在了机器人导航 增强现实和目标姿态估计中 DetectorParameters xff1a 检测标
  • PUTTY连接虚拟机linux,出现connection refused的解决方法!

    先确认是否已经给UBUNTU安装了SSHD 在终端输入SSHD 若未安装 xff0c 按提示安装 sudo apt get install openssh server 若出现以下问题 xff1a E Could not get lock
  • docker-compose部署emqx集群 配置带mysql授权认证

    EMQX 是一款大规模可弹性伸缩的云原生分布式物联网 MQTT 消息服务器 作为全球最具扩展性的 MQTT 消息服务器 xff0c EMQX 提供了高效可靠海量物联网设备连接 xff0c 能够高性能实时移动与处理消息和事件流数据 xff0c
  • ES6(ECMAScript6)新特性

    点击打开链接 箭头操作符 ES6中新增的箭头操作符 61 gt 简化了函数的书写 xff0c 操作符左边为输入的参数 xff0c 右边是进行的操作以及返回的值 引入箭头操作符后可以方便地写回调了 xff1a var array 61 1 2
  • K8s --HPA容器水平伸缩

    目录 一 什么是HPA 1 HPA伸缩过程 2 HPA进行伸缩算法 二 HPA实例 创建HPA 1 压力测试 2 同时监控cpu和memory 一 什么是HPA HPA的全称为 xff08 Horizontal Pod Autoscalin
  • linux磁盘读写命令,ubuntu命令行查看硬盘使用情况

    linux磁盘读写命令 ubuntu命令行查看硬盘使用情况 除了CPU和内存 xff0c 硬盘读写 I O 能力也是影响Linux系统性能的重要因素之一 本节介绍了可用于检查硬盘读写性能的几个系统命令 xff0c 并介绍了如何根据这些命令的
  • byr论坛技术楼

    链接 xff1a http bbs byr cn article MobileTerminalAT 17730 p 61 1
  • Zabbix5系列-监控华为、H3C交换机(snmpv2c/snmpv3/snmptrap) (二)

    Zabbix5系列 监控华为 H3C交换机 一 参考二 配置交换机2 1 华为SNMP v2c版本2 2 华为SNMP v3版本2 3 H3C SNMP v2c版本2 4 H3C SNMP v3版本 三 添加主机3 1 snmp v2c创建
  • docker 之普通用户运行

    ubuntu 不加sudo 执行 docker 时报错 Got permission denied while trying to connect to the Docker daemon socket at unix var run do
  • matlab simulink 自定义bus使用

    使用matlab simulink 可以方便的查看数据 xff0c simulink支持自定义bus xff0c 在bus中可以自定义数据结构 其中需要注意的是 xff0c 自定义的数据结构是有顺序的 xff0c 当signal需要和bus
  • stl container adapter

    容器适配器 xff1a stack queue priority queue stack Definition namespace std template lt typename T typename Container 61 deque
  • C 字符串获取元素地址

    打印出c字符串元素的地址 xff0c 需要将取地址符号 amp 进行静态类型转换为 void xff0c 或者使用static cast lt void gt 进行转换 const char p 61 34 abcdefg 34 char
  • MarkDown 内部跳转链接

    最近在用markdown写文档 xff0c 文档中需要有内部跳转链接 在此记录下可行的办法 这边我用表格中的文字跳转到另一个表格为例子 xff1a 表格1 商品 价格 备注 iphone13 6000 xff5e 10000 可参考采购平台
  • 深度学习 - TensorFlow Lite模型,云侧训练与安卓端侧推理

    TensorFlow Lite模型 xff0c 云侧训练与安卓端侧推理 引言一 云侧深度模型的训练代码1 加载数据集的格式分析1 1 从数据集加载的数据格式1 2 对加载的数据进行处理 2 深度模型搭建3 模型训练 评估 保存 转换4 模型

随机推荐

  • 无人驾驶-激光雷达与相机联合校准(Lidar Camera Calibration)

    1 激光雷达与摄像头性能对比 在无人驾驶环境感知设备中 xff0c 激光雷达和摄像头分别有各自的优缺点 摄像头的优点是成本低廉 xff0c 用摄像头做算法开发的人员也比较多 xff0c 技术相对比较成熟 摄像头的劣势 xff0c 第一 xf
  • vim c++开发

    vim 编写c 43 43 代码的快捷键 代码折叠 zf 创建折行 xff0c f 表示 foldzo 打开折行 xff0c o 表示 openzc 关闭折行 xff0c c 表示 closezd 删除折行 xff0c d 表示 delet
  • ros2 colcon

    ros2 项目构建之colcon 常用指令 colcon build symlink install cmake args DCMAKE BUILD TYPE 61 Release packages up to lt name of pkg
  • vscode docker clangd

    配置中报错 xff0c 找不到omp h头文件 sudo ln s usr lib gcc x86 64 linux gnu 9 include omp h usr include omp h
  • ros CMakeLists.txt template

    这里记录一个使用ros的CMakeLists txt的模板 xff0c 方便以后套用 示例 cmake minimum required VERSION 3 0 2 project rs parse set CMAKE CXX FLAGS
  • python 读取csv文件绘图

    python 读取csv文件数据 xff0c 然后通过plot绘图 bin bash python import csv import numpy as np from matplotlib import pyplot as plt col
  • ros utest

    在ros框架下编写代码 xff0c 在CMakeLists txt配置好之后 xff0c 在编译的时候执行下面指令即可生成测试代码的可执行文件 catkin make run tests 代码发布前 xff0c 测试用例一定要做好 xff0
  • boost 创建文件夹

    这里记录下如何使用boost创建文件夹的方法 主要步骤 包含filesystem头文件 include lt boost filesystem hpp gt 检测传入的文件目录 log path 是否存在 xff0c 目录不存在的话会新建一
  • GVINS论文阅读笔记

    Code Pseudorange Measurement c o d e p s e
  • matlab 读取csv文件绘图

    话不多说 xff0c 直接上代码 读取csv文件然后绘图 clc data 61 csvread 39 home lyb tools matlab files test csv 39 x 61 data 1 y 61 data 2 t 61
  • vins-mono初始化代码分析

    大体流程 初始化主要分成2部分 xff0c 第一部分是纯视觉SfM优化滑窗内的位姿 xff0c 然后在融合IMU信息 这部分代码在estimator processImage 最后面 主函数入口 xff1a void Estimator p
  • 浅谈嵌入式驱动设计

    一 总体说明 提到嵌入式的概念 xff0c 一时间脑容量已经容纳不下 xff0c 转到驱动的设计刚刚好 xff0c 习惯将一件事分层次去做 xff0c 驱动设计亦是如此 xff0c 很多人做工程时因为项目的时间紧张 xff0c 直接想到如何
  • 激光数据去畸变

    机械激光雷达产生数据原理 机械激光雷达中内置高速旋转的电机 xff0c 电机旋转的频率决定了激光雷达产生数据的频率 比如一个fov为360度的激光雷达 xff0c 每秒旋转一圈 xff0c 那么激光数据的频率就是1Hz xff1b 如果每秒
  • rosbag 录包

    ros提供了方便的录包指令 xff0c 基本使用如下 xff1a rosbag record topic 1 topic 2 这里记录下 xff0c 类似于滑动窗口的方式录制指定size的N个bag包 这主要用于只录制最近一段时间的数据包
  • pyhon记录cpu数据并保存到日志

    import logging import psutil time import re string log filename 61 34 logging txt 34 log format 61 39 asctime s message
  • ubuntu 修改重启时间

    ubuntu 默认重启时间过长 xff0c 默认为90s xff08 太久了 xff09 xff0c 下面为修改重启时间的正确姿势 cd etc systemd sudo vim system conf 打开文件后将下面这两行取消注释并修改
  • 数据分析实战(一):2019北大软微考研初试分析

    2019考研的初试成绩陆续放出 xff0c 也是几家欢喜几家愁 北大确实公平公正公开 xff0c 所有成绩 xff0c 排名在其研招网均能悉数找到 xff0c 下面选取了较为热门的北大软件与微电子学院考研初试成绩进行数据分析 导入excel
  • 程序员如何写项目经历

    对于程序员的简历来说 xff0c 简历的好坏可能影响着你能不能拿到满意的offer和薪资 xff0c 所以写一份高质量的简历 xff0c 突出自己技术能力非常重要 xff0c 就大家如何写简历中最重要的项目经历部分给出一些建议 了解项目的背
  • TypeError: iter() returned non-iterator of type ‘xxx‘

    最近在读 Python高级编程 xff08 Ziade著 xff09 xff0c 看到里面的自我设计的迭代器 xff1a 自己写的 xff1a span class token keyword class span span class t
  • memcpy与memmove函数的区别和实现

    1 函数定义 memcpy与memmove都是C语言的库函数 xff0c 在头文件string h中 xff0c 作用是内存拷贝 唯一的区别是 xff0c 当内存发生局部重叠时 xff0c memmove保证了拷贝的结果是正确的 xff0c