探索内存函数的奥秘【memcpy、memmove、memset、memcmp】

news2025/3/13 12:52:46

目录

一,memcpy函数

1,memcpy函数简介

2,memcpy函数的原理

3,memcpy函数的用法

4,注意事项

5,memcpy函数模拟实现

二,memmove函数

1,memmove函数简介

2,memmove函数的原理

3,memmove函数的用法

4,注意事项

5,memmove函数模拟实现

三,memset函数

1,memset函数简介

2, memset函数的原理

3,memset函数的用法

4,注意事项

四,memcmp函数

1,memcmp函数简介

2,memcmp函数功能

3,memcmp函数的用法 


一,memcpy函数

1,memcpy函数简介

memcpy函数的作用是将源内存块的内容复制到目标内存块中。

🌴函数头文件: 

#include <string.h>

 🌴函数原型:

void * memcpy ( void * destination, const void * source, size_t num );
  • dest:目标内存块的起始地址。
  • src:源内存块的起始地址。
  • num:要拷贝的字节数。
  • 该函数返回指向目标内存块的指针。

2,memcpy函数的原理

  • 它通常采用字节拷贝的方式来实现内存块的复制
  • 具体来说,memcpy函数会从源内存块中逐个字节地读取数据,并将其逐个字节地写入目标内存块中,直到拷贝完成为止。
  • 由于这种逐字节的拷贝方式,memcpy函数在处理大内存块时可能会比较耗时,因此在一些情况下可能会有更高效的替代方案。

3,memcpy函数的用法

将arr1数组里边的数(在内存中占20个字节)拷贝到arr数组里边去。

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

int main()
{
	int arr[10] = { 0 };
	int arr1[] = { 1,2,3,4,5 };

	memcpy(arr, arr1, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}

	return 0;
}

 🌴运行结果:

4,注意事项

  1. 内存重叠: 源内存块和目标内存块通常不应该重叠,否则会导致未定义的行为。

  2. 边界检查:需要确保拷贝的字节数不超过源内存块和目标内存块的实际大小,以免发生越界访问。

  3. 指针类型:需要注意指针类型的转换,确保传递给memcpy函数的参数类型正确。

5,memcpy函数模拟实现

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

void* my_memcpy(void* dest, 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;
}

int main()
{
	int arr[10] = { 0 };
	int arr1[] = { 1,2,3,4,5 };
	my_memcpy(arr, arr1, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

二,memmove函数

1,memmove函数简介

memmove函数的作用是将源内存块的内容移动到目标内存块中。与memcpy函数不同的是,memmove函数能够处理源内存块和目标内存块重叠的情况。

 🌴函数头文件:

#include <string.h>

 🌴函数原型:

void * memmove ( void * destination, const void * source, size_t num );
  • dest:目标内存块的起始地址。
  • src:源内存块的起始地址。
  • num:要移动的字节数。
  • 该函数返回指向目标内存块的指针。

2,memmove函数的原理

  • memmove 函数的实现原理会比memcpy稍微复杂一些,因为它需要处理源内存块和目标内存块重叠的情况。
  • 通常,memmove函数会采用一种类似于缓冲区的机制,先将源内存块的内容复制到一个临时缓冲区中,然后缓冲区的内容复制到目标内存块中,从而避免了重叠拷贝导致的数据错乱。
  • 这种机制使得memmove函数在处理重叠内存块时能够保证正确的移动操作。

3,memmove函数的用法

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

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

	memmove(arr, arr + 2, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}

	return 0;

  🌴运行结果:

4,注意事项

  1. 内存重叠: 虽然memmove函数能够处理重叠的内存块,但仍需谨慎处理,以免出现意外的情况。

  2. 边界检查:确保拷贝的字节数不超过源内存块和目标内存块的实际大小,以免发生越界访问。

  3. 指针类型:需要注意指针类型的转换,确保传递给memmove函数的参数类型正确。

5,memmove函数模拟实现

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

void* my_memmove(void* dest, const void* src, size_t sz)
{
	void* ret = dest;
	assert(dest && src);

	if (dest < src)
	{
		//前->后
		while (sz--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		//后->前
		while (sz--)
		{
			*((char*)dest + sz) = *((char*)src + sz);
		}
	}
	return ret;
}

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

	memmove(arr, arr + 2, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}

	return 0;
}

三,memset函数

1,memset函数简介

memset函数的作用是将指定内存块的内容设置为指定的值。

 🌴函数头文件:

#include <string.h>

  🌴函数原型:

void * memset ( void * ptr, int value, size_t num );
  •  ptr:指向要设置数值的内存块的指针
  • value:要设置的值
  • num:要设置的字节数
  • 该函数返回值指向内存块的指针

2, memset函数的原理

  •  通常使用一个循环来逐个字节地设置内存块的内容为指定的值
  • 由于内存的底层表示是字节,因此逐字节设置是一种通用且高效的方法
  • 在某些特定的平台上,memset函数可能会进行一些优化,以提高性能

3,memset函数的用法

🍁示例1:初始化数组:

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

int main()
{
	int arr[5];
	
	//将数组所有的元素初始化为0
	memset(arr, 0, sizeof(arr));
	for (int i = 0; i < 5; i++)
	{
		printf("%d", arr[i]);
	}

	return 0;
}

   🌴运行结果:


🍁示例2:清空字符串: 

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

int main()
{
	char str[] = "hello world";

    //将字符串str的所有字符设置为0
	memset(str, 0, sizeof(str));

    //输出空字符串
	printf("%s\n", str);

	return 0;
}

    🌴运行结果:

🌴调试时内存中情况: 


🍁示例3:内存分配和释放: 

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

int main()
{
	char* str = (char*)malloc(10 * sizeof(char));

	//对动态分配的内存进行初始化
	memset(str, 0, 10 * sizeof(char));
	strcpy(str, "hello");
	printf("%s\n", str);//输出:hello
	free(str);//释放内存

	return 0;
}

     🌴运行结果:

4,注意事项

  • 内存越界:确保设置的字节数不超过内存块的实际大小,以避免发生越界访问

  • 指针类型:需要注意指针类型的转换,确保传递给memset函数的参数类型正确

  • 对结构体和类的使用:在对结构体和类的内存块进行初始化时,需要谨慎处理,以避免出现意外的情况 

四,memcmp函数

1,memcmp函数简介

memcmp函数可以比较两个内存块的内容是否相等,并返回比较结果,通常用于比较字符串、数组或者其它内存块的内容。

  🌴函数头文件:

#include <string.h>

  🌴函数原型:

int memcmp ( const void * ptr1, const void * ptr2, size_t num );
  • ptr1:要比较的第一个内存块的起始地址。
  • ptr2:要比较的第二个内存块的起始地址。
  • num:要比较的字节数。

2,memcmp函数功能

  • 按字节逐个比较两个内存块中的内容,直到比较了num个字节或者遇到不相等的字节为止。

  • 如果两个内存块的内容完全相等,则返回0。

  • 如果第一个内存块小于第二个内存块,则返回一个负数。

  • 如果第一个内存块大于第二个内存块,则返回一个正数。 

3,memcmp函数的用法 

🍂示例1:比较字符串:

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

int main()
{
	char str1[] = "hello";
	char str2[] = "world";
	if (memcmp(str1, str2, 5) == 0)
	{
		printf("两个字符串相等\n");
	}
	else
	{
		printf("两个字符串不相等\n");
	}

	return 0;
}

   🌴运行结果:


🍂示例2:比较数组:

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

int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 1,2,3,4,6 };
	if (memcmp(arr1, arr2, 5 * sizeof(int) == 0))
	{
		printf("两个数组相等\n");
	}
	else
	{
		printf("两个数组不相等\n");
	}

	return 0;
}

   🌴运行结果:

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

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

相关文章

文件夹批量改名技巧:简单步骤,实现文件夹随机重命名

在日常生活和工作中&#xff0c;经常需要处理大量的文件夹&#xff0c;需要对其进行有效的管理。在这些情况下&#xff0c;文件夹的命名就变得非常重要。一个好的命名策略可以快速找到所需的文件夹&#xff0c;也可以帮助更好地组织文件。然而&#xff0c;手动为每个文件夹重命…

Ocelot:.NET开源API网关提供路由管理、服务发现、鉴权限流等功能

随着微服务的兴起&#xff0c;API网关越来越常见。API网关是连接应用程序和用户之间的桥梁&#xff0c;就像一个交通指挥员&#xff0c;负责处理所有进出应用的数据和请求&#xff0c;确保安全、高效、有序地流通。 今天给大家推荐一个.NET开源API网关。 01 项目简介 Ocelot…

通过easyexcel导出数据到表格

这篇文章简单介绍一下怎么通过easyexcel做数据的导出&#xff0c;使用之前easyui构建的歌曲列表crud应用&#xff0c;添加一个导出按钮&#xff0c;点击的时候直接连接后端接口地址&#xff0c;在后端的接口完成数据的导出功能。 前端页面完整代码 let editingId; let request…

智链引擎CEO李智:游戏化增长中台,让裂变营销快十倍、便宜十倍、好十倍丨数据猿专访...

大数据产业创新服务媒体 ——聚焦数据 改变商业 双十一电商大战一触即发&#xff0c;各个垂类的App也都希望能够借力双十一营销季&#xff0c;实现用户和营收双增长。MarTech在这个风口上&#xff0c;又成为2B赛道关注的焦点。 业内人士指出&#xff0c;MarTech的引入催生营销…

毅速丨金属3D打印零件品质受哪些因素影响

金属3D打印的零件品质受到多个因素的影响&#xff0c;包括设备、材料、工艺、后处理等。不同厂商的品质差别大致由以下几个方面造成。 一、设备性能差异&#xff1a; 不同厂商的金属3D打印设备可能存在性能上的差异&#xff0c;包括激光功率、扫描速度、打印精度、稳定性等。这…

【教3妹学编程-算法题】765. 情侣牵手

3妹&#xff1a;2哥2哥&#xff0c;你看到新闻了吗&#xff1f;襄阳健桥医院院长 公然“贩卖出生证明”&#xff0c; 真是太胆大包天了吧。 2哥 : 我也看到新闻了&#xff0c;7人被采取刑事强制措施。 就应该好好查查他们&#xff0c; 一查到底&#xff01; 3妹&#xff1a;真的…

Python:词法分析(行结构与显式、隐式行拼接)

相关阅读 Pythonhttps://blog.csdn.net/weixin_45791458/category_12403403.html?spm1001.2014.3001.5482 1、逻辑结构 一个Python程序由许多逻辑行组成&#xff0c;字面意义上的一行指的是末尾有换行符(\n)&#xff0c;但在不同的情况下&#xff0c;行末尾的换行符(\n)可能有…

如何选择一个可靠的爬虫代理服务商?技术人员都需要知道

我身边从事大数据相关行业的朋友最近告诉我&#xff0c;自己新招的小伙伴工作效率很低&#xff0c;很多最基础的工具都不会选择&#xff0c;经常因为代理IP不可靠导致工作出错。 听完这些我才意识到&#xff0c;在这个大数据时代&#xff0c;还是有很多新手在进行网络爬取任务…

Elasticsearch 和 Go 中使用向量搜索寻找地鼠

作者&#xff1a;CARLY RICHMOND&#xff0c;LAURENT SAINT-FLIX 就像动物和编程语言一样&#xff0c;搜索也经历了不同实践的演变&#xff0c;很难在其中做出选择。 加入我们的第二部分&#xff0c;通过 Elasticsearch 中的矢量搜索在 Go 中狩猎地鼠&#xff08;gophers&…

沁恒微WCH592程序烧录问题

在使用wch592蓝牙芯片时&#xff0c;使用WCHISPStudio_V3.60工具烧录hex固件时&#xff0c;识别设备OK&#xff0c; 擦除flash OK&#xff0c;就是在烧录时一直报错&#xff0c;错误如下&#xff1a; 原因是:代码和数据保护模式没有启用。 改为如下&#xff1a;

Git可视化界面的操作,SSH协议的以及IDEA集成Git

目录 一. Git可视化界面的操作 二. gitee的ssh key 2.1 SSH协议 2.2 ssh key 三. IDEA集成Git 3.1 分享项目 3.2 下载项目 一. Git可视化界面的操作 上一篇博客只用到了git的命令窗口&#xff0c;现在就来看看可视化窗口要怎么操作。 点击Git GUI Here GUI界面 在g…

由于找不到 d3dx9_43.dll,无法继续执行代码。重新安装程序可能会解决此问题

电脑出现d3dx9_43.dll缺失的问题&#xff0c;通常是由于DirectX组件未安装或损坏导致的。为了解决这个问题&#xff0c;我为您提供了以下四个解决方法&#xff1a; d3dx9_43.dll解决方法1. 使用dll修复程序修复 首先&#xff0c;使用系统文件程序dll进行修复操作非常简单&…

ZYNQ_project:IP_ram_pll_test

例化MMCM ip核&#xff0c;产生100Mhz&#xff0c;100Mhz并相位偏移180&#xff0c;50Mhz&#xff0c;25Mhz的时钟信号。 例化单口ram&#xff0c;并编写读写控制器&#xff0c;实现32个数据的写入与读出。 模块框图&#xff1a; 代码&#xff1a; module ip_top(input …

人工智能与养老:技术助力银色产业的崛起

人工智能与养老&#xff1a;技术助力银色产业的崛起 随着人口老龄化的加速推进&#xff0c;养老问题成为了全球关注的热点。人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;为养老领域注入了新的活力。本文将探讨人工智能在养老领域的应用、关键挑战以及前景展望…

计算机毕业设计:水果识别检测系统 python 深度学习 YOLOv5

[毕业设计]2023-2024年最新最全计算机专业毕设选题推荐汇总 感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;希望帮助更多的人 。 1、项目介绍 本文介绍了一种基于深度学习的水果检测与识别系统…

【解决方案】pytion 运行时提示 import psutil ModuleNotFoundError: No module named ‘psutil‘

报错原因分析 import psutil ModuleNotFoundError: No module named psutil报错原因分析 当前环境pytion中缺少了psutil包&#xff0c;使用pip命令进行安装 解决方案 pip install psutil

十八数藏的新时代探索:数字创新助推文化保护

在这个数字化的新时代&#xff0c;传统文化和数字创新的结合呈现出令人振奋的新面貌。十八数藏&#xff0c;作为文化数字创新的佼佼者&#xff0c;正以数字化的手段助推文化的保护与传承。 十八数藏通过数字技术&#xff0c;将传统非物质文化遗产以数字形式呈现&#xff0c;使其…

【代码随想录】算法训练计划18

1、513. 找树左下角的值 题目&#xff1a; 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 思路&#xff1a; 递归&#xff0c;规则&#xff0c;基本可以自己写出来 var maxDepth int var res int fun…

基于安卓android微信小程序的四六级助手系统

项目介绍 随着我国教育需求不断增加&#xff0c;高校教育资源有限&#xff0c;教育经费相对不足的情况下&#xff0c;利用现代信息技术发展高等教育&#xff0c;不仅充分利用了优秀的教育资源&#xff0c;而且为更多的人提供接受高等教育的机会&#xff0c;同时这也是极大促进…

【开源】基于Vue.js的智能停车场管理系统的设计和实现

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容A. 车主端功能B. 停车工作人员功能C. 系统管理员功能1. 停车位模块2. 车辆模块3. 停车记录模块4. IC卡模块5. IC卡挂失模块 三、界面展示3.1 登录注册3.2 车辆模块3.3 停车位模块3.4 停车数据模块3.5 IC卡档案模块3.6 IC卡挂…