关于内存函数memcpy、memmove解析

安全拷贝函数safe_memcpy实现分析 一 memcpy缺陷分析 1.memcpy原型: #include <string.h> void *memcpy(void *dest, const void *src, size_t n); #函数返回dest指针 2.缺陷分析: (1)memcpy容易发生缓冲区溢出,如果dest长度小于待拷贝的字节数n,那么程序将发生缓冲区溢出; (2)如果dest是高地址,src是低地址,拷贝可能发生错误,即源地址和目的地址重合部分在拷贝时被修改。 ... 阅读详情

目录

1、函数声明

2、功能

3、举例

4、模拟实现

 二、memmove

1、函数声明

2、功能

3、举例

4、模拟实现


一、memcpy

1、函数声明

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

其中的参数分别是:

destination——目的地,

source——源头,

num——要复制的字节数(size_t是无符号整型)。 

2、功能

 从上面的参数,我们也可以想到,这是个内存拷贝的函数,将数字字节的值从源头指向的位置直接复制到目标所指向的内训块。

3、举例

#include<stdio.h>
#include<string.h>

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 0 };
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	memcpy(arr2, arr1, sizeof(int) * sz);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr2[i]);//输出结果为1——10
	}
	return 0;
}

4、模拟实现

#include<stdio.h>
#include<assert.h>
#include<string.h>

//模拟实现memcpy

void* my_memcpy(void* str1, const void* str2, size_t num)
{
	assert(str1 && str2);
	char* str = str1;
	while (num--)
	{
		(*(char*)str1) = (*(char*)str2);
		/*((char*)str1)++;
		((char*)str2)++;*/
		//有些编译器跑不过去
		str1 = (char*)str1 + 1;
		str2 = (char*)str2 + 1;
	}
	return str;
}

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	my_memcpy(arr2, arr1, sizeof(int) * sz);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

但是如果我们想把arr1中的前3个元素,即1,2,3拷贝到3,4,5的位置上去,就会出现不一样的结果,我们用调试的方式来看一看。

这里我们还没执行my_memcpy,再按一次F10,走!

数组里的内容变了,但是不是我们想要的结果,这是为什么呢? 

那有没有一个函数能做到拷贝重叠内存块呢?

这里我们就扯到了memmove函数了。


 二、memmove

1、函数声明

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

2、功能

其实它的功能和memcpy差不多,区别就是在于memcpy不可以拷贝重叠的内存块,而memmove可以。

3、举例

#include<stdio.h>
#include<string.h>

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr + 2, arr, sizeof(int) * 3);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);//输出结果1 2 1 2 3 6 7 8 9 10
	}
	return 0;
}

4、模拟实现

实现思路:

可以理解为memmove是memcpy的plus版本,所以我们只需要在memcpy的基础上加一个能拷贝重叠内存块的功能。

我们把重叠部分的拷贝分为3种情况:

1、如果目的地在源头的后面

 

 所以,当目的地在源头的后面时,从后面开始拷贝。

2、如果目的地和源头的地址相同,则不需要考虑。

3、如果目的地在源头的前面

所以, 如果目的地在源头的前面时,从前面开始拷贝。

这样我们就可以理解为当目的地在源头的后面时,从后面开始拷贝,当目的地在源头的前面或者目的地和源头的位置相同时,从前面开始拷贝。

思路有了,开始写代码:

#include<stdio.h>
#include<assert.h>
#include<string.h>

void* my_memmove(void* str1, void* str2, size_t num)
{
	void* ret = str1;
	assert(str1 && str2);
	if (str1 < str2)
	{
		while (num--)
		{
			*(char*)str1 = *(char*)str2;
			str1 = (char*)str1 + 1;
			str2 = (char*)str2 + 1;
		}
		
	}
	else
	{
		while (num--)
		{
			*((char*)str1 + num) = *((char*)str2 + num);
		}
	}
	return ret;
}


int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr1 + 3, arr1, sizeof(int) * 5);
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}
memcpy缺陷探讨 前一篇文章描述了memcpy的实现方法,本文将探讨下memcpy运用中存在的缺陷,即memcpy不能拷贝目的地址(dest)和源地址(src)内存空间有重合的部分,更为确切的说应该是当目的地址大于源地址的时候,不能够有重合部分,否则源地址重合部分数据会发生错误 以下分析只考虑目的地址和源地址有数据重合情况,在没有数据重合情况的时候,memcpy是能够正确的使用,不会出现错误 1、当目的地址(d 阅读详情

相关推荐

深入解析C/C++内存函数:从memcpy到memmove的实战避坑指南

内存操作是C/C++编程的核心基础,涉及对原始内存字节的直接读写,其核心原理在于绕过类型系统,以字节为单位进行高效处理。理解内存对齐、字节序等底层概念,对于编写高性能和健壮的系统软件至关重要。这些技术的价值在于提供了接近硬件极限的数据操作能力,广泛应用于网络编程、音视频处理、嵌入式系统及自定义数据结构实现等场景。本文将聚焦于memcpy、memmove、memset和memcmp这四个关键函数,通过剖析内存重叠、结构体填充字节等典型陷阱,并结合memcpy性能优化和memmove安全拷贝等实战案例,帮助开发

weixin_34379433的博客 369

memcpy内存重叠的解决及其实现

void * memcpy(void * destination, const void * source, size_t num); 当源字节串和目标字节串重叠是,bcopy能够正确处理,但是memcpy的操作结果不得而知,这种情况必须改用ANSI C的memmove函数[网络编程]。故该函数实现过程中要考虑src 和dst是否有重叠的情况。 内存重叠:拷贝的目的地址在源地址范围内。所谓内存...

suyinfan的博客 5450

C语言内存操作函数深度解析:从memcpy到memmove的内存重叠处理

内存操作是C/C++编程的核心基础,理解其底层原理对编写高效、安全的代码至关重要。内存拷贝函数如memcpy通过直接操作内存地址实现数据的高效传输,其本质是字节级的搬运工。然而,当源内存与目标内存区域存在重叠时,简单的顺序拷贝会导致数据污染,这是内存操作中一个经典且易被忽视的边界问题。为了解决这一问题,标准库引入了memmove函数,它通过智能判断重叠方向(正向或反向)并选择相应的拷贝顺序(从低地址到高地址或反之),确保了重叠拷贝的正确性。这种对内存布局和拷贝顺序的精细控制,体现了底层编程对程序鲁棒性和严谨

weixin_29279101的博客 294

【C++】memcpy的原理以及速度快的原因

memcpy的原理以及速度快的原因

weixin_39390491的博客 5097

手把手教你用HI3516CV610搭建智能安防摄像头(附完整开发资料)

本文详细介绍了基于海思HI3516CV610 SOC搭建智能安防摄像头的完整开发流程,包括硬件选型、系统架构设计、开发环境搭建、智能分析功能开发及系统调优。通过实战案例,展示了如何利用内置NPU实现人形检测和异常行为分析,并提供了量产测试方案,帮助开发者快速完成智能摄像头项目。

backprop5master的博客 545

OpenClaw实操:给网站装上“智能眼睛”?手把手教你用OpenClaw实时监控网站

本文介绍如何在Windows系统使用OpenClaw构建智能网站监控助手。手把手教你通过配置本地AI模型,让openclaw构建的ai助手自动检测指定网页的内容变化,理解更新重要性,并及时通过邮件、微信、Telegram等渠道发出预警,让你第一时间掌握关键信息,彻底告别手动刷新。

plawuyue的博客 2163

memcpy内存重叠问题

memcpy内存重叠之前一直没有注意到内存复制函数的内存重叠问题。今天偶遇遂琢磨了一下,记之。函数简介:c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。一般避免内存重叠。没有内存重叠的情况:void *mymemcpy(void *dst,const void *src,size_t num) {

小李的专栏 6947

从零到一:龙芯杯参赛全攻略(含北理工学长经验PDF、B站培训视频与开源代码合集)

本文详细介绍了龙芯杯全国大学生计算机系统能力大赛的参赛全攻略,包括资源整合、技能树构建、团队协作和避坑指南。提供北理工学长经验PDF、B站培训视频与开源代码合集,帮助参赛者从零基础到站上领奖台。重点解析如何高效获取优质资源、避开新手常见陷阱及构建可落地的学习路径,助力普通学生系统学习CPU设计。

weixin_26802933的博客 542

【C语言】入门必看四大内存函数全解析:memcpy、memmove、memset、memcmp

你是否总是被 C 语言中的内存函数弄混? memcpy 和 memmove 究竟有何不同? memset 是如何高效初始化内存的? memcmp 为什么能比字符串比较更灵活? 别担心!这篇文章将从原理、代码实现、常见问题到优化技巧,全面剖析这四个内存函数的使用场景和注意事项。阅读完,你不仅能熟练运用这些函数,还能理解它们在 C 语言中的底层操作。

Marathon_X的博客 1153

均匀直线阵的常规波束形成matlab

常规波束形成概述 波束形成是将基阵各阵元输出进行一定的处理,从而形成基阵空间指向性的技术。一个波束形成器可以对空间某方位的信号有响应,而抑制其他方位的信号,所以又被称为空域滤波。一般分为常规波束形成(CBF)和自适应波束形成(ABF)。 常规波束形成较为基础,一般又可以根据实现的途径不同,分为时延波束形成和频移波束形成。 时延波束形成 在各阵元间添加时延使波束控制于不同方位的方法成为时延波束形成。设定一个目标方向,当信号来源方向在该目标方向时,响应最大;信号来源于其他方向时,响应较小。将这种响应大小

Xujing1143的博客 2万+

labelImg使用教程

Anaconda环境 安装 Anaconda 之后,在开始菜单下找到 Anaconda 文件夹 找到 Anaconda Prompt 点击运行 安装 labelImg pip install labelImg #直接命令行输入 启动 labelImg labelImg #直接命令行输入名称即可 labelImg界面 开始标注 快捷键:W(创建方框),A(上一张),D(下一张) XML文件示例 <annotation> <folder>夜读</folder>

G果的博客 3万+

C语言内存操作函数深度解析:从memcpy到memmove的实践指南

特别是部署后的演示页面,非常适合用来对比展示memcpy和memmove的行为差异,这种可视化学习方式比单纯看代码更易理解。作为通用内存拷贝函数,memcpy通过void*指针实现任意数据类型的内存块复制,其核心优势在于不依赖具体数据类型。函数通过指定字节数控制复制范围,但需注意其遇到\0不会自动终止的特性,这与字符串函数有本质区别。memmove通过智能判断拷贝方向解决重叠问题:当检测到dest<src时采用前向拷贝,否则使用(num-1)偏移量的逆向拷贝策略。正确用法是配合字符数组或清零操作。

GoldenleafTiger89的博客 425

如何使用事务码SMICM分析ABAP代码发起的HTTP请求的错误

当我用CL_HTTP_CLIENT往一个外网的url发请求时,遇到错误:ICM_HTTP_SSL_PEER_CERT_UNTRUSTED 错误是从这段ABAP代码里抛出来的: CALL METHOD lo_http_client-&gt;get_last_error IMPORTING code = lv_sysubrc message = ev_error_message. "BREAK-...

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 3209

《深入理解 C 语言内存操作函数:memcpy、memmove、memset 与 memcmp 全解析》

memcpy函数的原型如下:该函数用于将source指向的内存地址开始的num个字节数据复制到指向的内存地址。注意memcpy不会因为遇到'\0'而停止复制,且如果源地址与目标地址存在重叠,其行为是未定义的。memmove函数的原型与memcpy相同:与memcpy不同的是,memmove可以处理内存重叠的情况。它是更安全的复制函数。memset函数的原型如下:该函数用于将ptr指向的内存区域的前num个字节设置为value的值(按字节设置memcmp函数的原型如下:该函数用于比较ptr1。

月夜的风吹雨的博客 1117

RFSoC全面解析(八)—— ZCU111 RFSoC评估工具的上位机界面

下面的内容的参考文献为:XILINX公司文档UG1287。 XILINX公司提供了一个RFSoC的ADC/DAC性能的评估工具或者叫评估系统,这个文档就是讲如何使用这个评估工具的。 整个评估系统总的框图如上图所示,评估系统由上位机、ZCU111开发板、子卡以及网线、射频线缆组成。 ZCU111开发板内主要使用的RFSoC外设为时钟驱动和DDR4,RFSoC的PS部分和PL部分都使用了。 PS部分发挥的功能为通过网口与上位机通信,通过IIC总线控制时钟驱动芯片以及数据流控制等;PL部分发挥的功能为

4381

LED灯闪烁实验:代码集成

LED灯闪烁实验已经全部完成,在该实验中使用了较多的工具链,涉及底层软件、建模、软件编译等。首先,通过STM32CubeMX工具进行STM32底层软件配置,可以大大减少手写代码的工作量。另外由于做了可视化,也降低了STM32的上手难度,提升效率。利用Simulink建模,可以在PC环境下验证应用层算法的正确性而不依赖于具体控制器,实现应用层算法和底层软件、控制器硬件的解耦。另外,图形化的建模方式也更加有利于开发者思考与分析,大量的封装库文件也可以降低开发的工作量。

u013288925的博客 370

C语言内存函数深度解析:从memcpy到memmove的原理与模拟实现

在C语言程序开发中,内存操作是底层系统编程的核心基础。理解内存的布局与访问原理,是掌握指针、数据结构及性能优化的关键。内存函数(如memcpy、memmove、memset、memcmp)提供了一种按字节精确操作内存的机制,与字符串函数不同,它们不受'\0'终止符限制,能够处理任意二进制数据,从而在数据拷贝、缓冲区初始化、二进制比较等场景中发挥不可替代的作用。通过模拟实现这些函数,开发者可以深入理解指针运算、类型转换及内存重叠等底层概念,进而提升代码的健壮性与性能。本文以memcpy和memmove为例,详

weixin_33462927的博客 246

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

C语言内存操作函数深度解析:从memcpy到memmove的原理、陷阱与实战优化

内存操作是C语言编程的核心基础,它直接关系到程序的性能、安全性与稳定性。理解内存操作的底层原理,是掌握系统编程、嵌入式开发和高性能计算的关键。内存操作函数通过直接操作字节,实现了对任意数据类型的泛型处理,其技术价值在于提供了高效、灵活的数据搬运、初始化和比较能力。在应用场景上,从网络协议包的封装解析、自定义内存池的实现,到动态数组等数据结构的构建,都离不开这些函数的支撑。本文聚焦于memcpy、memmove、memset和memcmp等核心函数,深入剖析其行为差异、重叠内存处理、性能优化策略及常见陷阱,并

weixin_34238633的博客 499

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【C 语言进阶】内存函数核心知识点全解析:memcpy 与 memmove

特性memcpymemmove内存重叠支持不支持(结果未定义)支持实现复杂度简单(单向拷贝)复杂(区分方向拷贝)应用场景非重叠内存的高效拷贝重叠内存或不确定是否重叠的场景。

2301_80137336的博客 306

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

C语言内存函数深度解析:从memcpy、memmove到memset的实现原理与优化

内存操作是C语言编程的核心基础,理解其底层原理对于提升程序性能和稳定性至关重要。内存函数如memcpy、memmove和memset,作为标准库提供的利器,其高效性源于对计算机硬件特性的深度利用,尤其是内存对齐访问机制。通过内存对齐,CPU能以字(word)为单位批量读写数据,大幅减少内存访问次数,从而显著提升性能。在工程实践中,掌握这些函数的实现细节,不仅能帮助开发者编写更高效的代码,还能在调试内存相关错误时快速定位问题根源。例如,memcpy与memmove的关键区别在于对重叠内存区域的处理策略,这直接

weixin_32267731的博客 226

《C 语言内存函数深度剖析:从原理到实战(memcpy/memmove/memset/memcmp 全解析)》

本文详细解析了C语言中四种核心内存操作函数: memcpy:高效内存拷贝,但不处理重叠区域,需注意目标与源地址不能重叠; memmove:增强版memcpy,支持重叠内存拷贝,通过智能选择复制方向避免数据覆盖; memset:字节级内存初始化,适合清零或设置特定值,但对非char类型需谨慎使用; memcmp:按字节比较内存内容,基于无符号值返回差异结果。 关键要点包括:memcpy/memmove的单位是字节而非元素,memset仅修改低8位,memcmp按字典序比较。文中提供了各函数的模拟实现代码,帮助

2403_87581574的博客 1391

C语言内存函数全解析:从memcpy到memmove

在结束之前字符串函数的介绍后,我们接下来要介绍的是c语言中的另一类函数,内存函数。

xxxiugou123的博客 425

C语言内存函数深度解析:从memcpy、memmove到memcmp的模拟实现与优化

内存操作是C语言编程的核心基础,涉及数据在内存中的存储、搬运与比较。其原理基于指针运算和字节级访问,通过直接操作内存地址实现高效的数据处理。掌握内存操作函数的技术价值在于,能够编写出性能更高、更可靠的低层系统软件,如操作系统内核、嵌入式驱动和自研基础库。在嵌入式开发、高性能计算和系统编程等应用场景中,对内存行为的精确控制至关重要。本文聚焦于内存函数模拟实现,深入探讨了memcpy、memmove和memcmp的实现细节,特别是重叠内存处理与性能优化策略,帮助开发者从“黑盒”使用转向“白盒”理解,夯实指针与内

weixin_29200485的博客 333

C/C++内存函数深度解析:memcpy、memmove、memset、memcmp原理与实战避坑

内存操作是C/C++编程的基石,理解其底层原理对编写高效、安全的代码至关重要。内存函数通过直接操作字节实现数据复制、初始化和比较,其性能优化依赖于内存对齐和CPU指令集。在工程实践中,这些函数是数据结构序列化、缓冲区管理和内存池实现的核心工具。然而,不当使用会导致缓冲区溢出、数据覆盖等严重问题。本文聚焦memcpy与memmove的重叠处理差异、memset的字节操作特性以及memcmp的逐字节比较机制,结合内存对齐优化和编译器行为,深入探讨如何避免常见陷阱,确保代码健壮性。

weixin_34341229的博客 331

C语言内存函数深度解析:从memcpy到memmove的原理、实现与陷阱

在C语言编程中,内存操作是核心基础,涉及指针、缓冲区等关键概念。其原理在于直接对原始内存字节流进行读写,通过void*泛型指针和显式长度参数实现类型无关的灵活操作。这种底层控制能力的技术价值在于能够高效处理任意二进制数据,如结构体、网络数据包等,是系统编程和高性能计算的基石。应用场景广泛,包括数据结构实现、序列化反序列化、系统底层开发等。本文聚焦于memcpy、memmove、memset、memcmp等关键内存函数,通过模拟实现剖析其内部机制,并重点探讨memcpy与memmove在处理重叠内存时的差异与

weixin_33853794的博客 362

C/C++内存函数深度解析:memcpy、memmove、memset、memcmp的正确使用与性能陷阱

内存操作是计算机程序设计的基石,理解内存的读写、复制与比较原理是每位开发者的必修课。在C/C++等系统级编程语言中,内存函数直接操作底层字节,其性能与正确性直接影响程序的效率与稳定性。这些函数通过高效的字节级处理,为数据结构初始化、数据迁移和二进制比较提供了基础支持,在系统编程、嵌入式开发和高性能计算中不可或缺。然而,看似简单的函数背后隐藏着诸多陷阱,例如**内存重叠**导致的未定义行为,以及**结构体填充字节**引发的比较错误。本文以`memcpy`、`memmove`、`memset`和`memcmp`

weixin_30388677的博客 310
上一篇: 整形数据类型在内存中的储存及大小端的介绍
下一篇: 关于结构体类型的讲解
写bug还得是我
博客等级 码龄5年 71粉丝 26原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值