内存函数的介绍和模拟实现

news2024/11/28 16:30:48

目录

1.memcpy的使用(内存拷贝)

2.memcpy的实现

3.memmove的使用(内存拷贝)

 4.memmove的实现

5.memset 的使用(内存设置)

6.memcmp的使用(内存比较)


1.memcpy的使用(内存拷贝)

void * memcpy ( void * destination, const void * source, size_t num );
  • 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
  • 这个函数在遇到 '\0' 的时候并不会停下来。可能把字符'\0'也拷贝过去
  • 如果source和destination有任何的重叠,复制的结果都是未定义的

注意:对于拷贝时候内存存在重叠的情况,尽量不要使用memcpy。

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <string.h>
//memcpy的使用
struct {
	char name[40];
    int age;
    person, 
    person_copy
       };
int main()
{
	char myname[] = "Pierre de Fermat";

	memcpy(person.name, myname, strlen(myname) + 1);//将‘\0’也拷贝过去

	person.age = 46;

	memcpy(&person_copy, &person, sizeof(person));

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

	return 0;
}

将myname数组中的数据拷贝到person.name中。

2.memcpy的实现

我们使用对内存进行操作的函数。因此我们应当想到为了在处理不同数据类型时候一个函数便能解决大部分问题,因此我们可以看出内存函数的参数和返回值大部分都是void类型,并且我们在对内存操作时想到的是对内存一个字节一个字节进行操作。

#include<assert.h>
void* my_memcpy(const void* des, const void* src, size_t num)
{
	assert(des && src);
	const void* ret = des;
	//一个字节一个字节拷贝过去由此我们想到了char * 类型数据
	//数据拷贝
	int i = 0;
	for (i = 0; i < num; i++)
	{
		*(char*)des = *(char*)src;//转换类型便于对内存进行一个字节的操作
		des = (char*)des + 1;
		src = (char*)src + 1;
	}

	return ret;
}
int main()
{
	char name1[20] = "zhouhaotianxxx";
	char name2[] = "wangxilong";
	//使用模拟的memcpy函数实现将name2中的数据拷贝到name1中

	puts("name1最初的字符串是:zhouhaotian\0");
	printf("name1中的数据经过拷贝后变成了:%s\n", my_memcpy(name1, name2, strlen(name2))); //注意memcpy函数在遇到 '\0' 的时候并不会停下来,他是忠心以字节个数来进行拷贝的
	return 0;
}

3.memmove的使用(内存拷贝)

void * memmove ( void * destination, const void * source, size_t num );
  • 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
  • 如果源空间和目标空间出现重叠,就得使用memmove函数处理
#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

void* memmove(void* destination, const void* source, size_t num);
 
和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
 
如果源空间和目标空间出现重叠,建议使用memmove函数处理。
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	memcpy(arr, arr + 5, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");

	return 0;
}//可以看出在vs2022下memcpy也可以对源空间和目标空间出现重叠情况进行处理。

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

	return 0;
}//如果源空间和目标空间出现重叠,建议使用memmove函数处理。

 4.memmove的实现

由于我们知道了memcpy函数无法对内存块重叠情况下进行内存拷贝,由此我们需要使用或者实现一个新的函数能够完成此情况下的功能实现。

我们先画图分析一下:

 我们可看到当源头指针和目的地指针在指向同一块内存空间的内容时,他们两指向的前后顺序将会影响我们内存的拷贝。

第一种:

  •  src在dst之前,并且两者内容存在重叠的情况下:当我们仍然从前往后拷贝内容会发现我们想要拷贝的内容将会被覆盖,因此这种情况下我们应当从后往前拷贝。

 

  •  src在dst之后,并且两者内容存在重叠的情况下:当我们从后往前拷贝内容会发现我们想要拷贝的内容将会被覆盖,因此这种情况下我们应当从前往后拷贝。 

  •  而当内容并无内存重叠情况下我们从前往后拷贝或者从后往前拷贝便可以根据我们个人意愿来实现如何拷贝,下面给出代码实现。
#include<stdio.h>
#include<string.h>
#include<assert.h>

void* my_memmove(const void* dst, const void* src, size_t num)
{
	assert(dst && src);
	const void* ret = dst;
	//一个字节一个字节拷贝
	//数据拷贝
	int i = 0;
	//从后往前拷贝
	if (dst > src)
	{
		src = (char*)src + num - 1;
		dst = (char*)dst + num - 1;
		for (i = 0; i < num; i++)
		{
			*(char*)dst = *(char*)src;
			dst = (char*)dst - 1;
			src = (char*)src - 1;
		}
	}
	//从前面往后面拷贝
	if (dst <= src)
	{

		for (i = 0; i < num; i++)
		{
			*(char*)dst = *(char*)src;
			dst = (char*)dst + 1;
			src = (char*)src + 1;
		}
	}
	return ret;
}
int main()
{

	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr, arr + 2, 8);//模拟实现重叠内存拷贝函数

	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	//结果应该是3 4 3 4 5 6 7 8 9 10
	printf("\n");


	return 0;
}

5.memset 的使用(内存设置)

void * memset ( void * ptr, int value, size_t num );
  • 这个函数用于将 prt 指向的内存区域的前 num 个字节设置为 value 指定的值。它返回 ptr 的起始地址。
#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

//memset的使用
//以字节为单位设置内存
int main()
{
	char arr[] = "hello world";
	memset(arr + 2, 'x', 3);
	printf("%s\n", arr);
	return 0;
}

注意:memset是以字节为单位来设置内存的 !

6.memcmp的使用(内存比较)

int memcmp ( const void * ptr1, const void * ptr2, size_t num );
  • 比较从ptr1和ptr2指针开始的num个字节
  • 返回值是int类型

返回值如下图:

  • memcmp比较比较的是内存块(可以指定比较字节数)
  • 而strcmp只能比较字符串

 

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
//memcmp的使用
int main()
{
	int a[] = { 1,2,3,4,5,6,7 };
	int b[] = { 1,2,3,5, };
	printf("%d\n", memcmp(a, b, 12));
	printf("%d\n", memcmp(a, b, 16));
	return 0;
}


希望大佬们一键三连,您的支持是对我最大的鼓励! 

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

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

相关文章

【C++】C++11------线程库

目录 线程库接口线程接口使用lock_guard与unique_lockmutex(互斥锁)lock_guardunique_lock 原子性操作库条件变量(condition_variable) 线程库接口 在C11之前&#xff0c;涉及到多线程问题&#xff0c;都是和平台相关的&#xff0c;比如windows和linux下各有自己的接口&#x…

PMSM——转子位置估算基于QPLL

文章目录 前言仿真模型观测器速度观测位置观测转矩波形电流波形 前言 今后是电机控制方向的研究生的啦&#xff0c;期待有同行互相交流。 仿真模型 观测器 速度观测 位置观测 转矩波形 电流波形

Fake Maxpooling 二维滑动窗口

先对每一行求一遍滑动窗口&#xff0c;列数变为(列数-k1) 再对每一列求一遍滑动窗口&#xff0c;行数变为(行数-k1) 剩下的就是每一个窗口里的最大值啦 #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define endl \nusing nam…

【图论C++】链式前向星(图(树)的存储)

/*** file * author jUicE_g2R(qq:3406291309)————彬(bin-必应)* 一个某双流一大学通信与信息专业大二在读 * * brief 一直在竞赛算法学习的路上* * copyright 2023.9* COPYRIGHT 原创技术笔记&#xff1a;转载需获得博主本人…

idea debug 重启弹窗提示窗口询问是否关闭运行着的服务器

目录 方法121版本的IDEA idea重新启动服务器时会有一个提示窗口询问是否关闭运行着的服务器&#xff0c;&#xff0c;这个窗口不小心点了不再提示.重新打开弹窗方法 方法1 idea编辑器由于勾选了不再提示选项导致的弹窗无法继续弹出&#xff1a;解决方案 1.打开项目没提示&…

Rust 使用Cargo

Rust 使用技巧 Rust 使用crates 假设你正在编写一个 Rust 程序&#xff0c;要使用一个名为 rand 的第三方库来生成随机数。首先&#xff0c;你需要在 Cargo.toml 文件中添加以下依赖项&#xff1a; toml [dependencies] rand "0.7.3" 然后运行 cargo build&…

Mybatis 二级缓存(使用Ehcache作为二级缓存)

上一篇我们介绍了mybatis中二级缓存的使用&#xff0c;本篇我们在此基础上介绍Mybatis中如何使用Ehcache作为二级缓存。 如果您对mybatis中二级缓存的使用不太了解&#xff0c;建议您先进行了解后再阅读本篇&#xff0c;可以参考&#xff1a; Mybatis 二级缓存https://blog.c…

VisionTransformer(ViT)详细架构图

这是原版的架构图&#xff0c;少了很多东西。 这是我根据源码总结出来的详细版 有几点需要说明的&#xff0c;看架构图能看懂就不用看注释了。 &#xff08;1&#xff09;输入图片必须是 224x224x3 的&#xff0c;如果不是就把它缩放到这个尺寸。 &#xff08;2&#xff09;T…

文本嵌入层

1、代码演示 embedding nn.Embedding(10,3) print(embedding) input torch.LongTensor([[1,2,3,4],[4,3,2,9]]) embedding(input) 2、构建Embeddings类来实现文本嵌入层 # 构建Embedding类来实现文本嵌入层 class Embeddings(nn.Module):def __init__(self,d_model,vocab):…

uboot启动流程-涉及_main汇编函数

一. uboot启动流程涉及函数 本文简单分析一下 save_boot_params_ret调用的函数&#xff1a;_main汇编函数。 本文继之前文章的学习&#xff0c;地址如下&#xff1a; uboot启动流程-涉及s_init汇编函数_凌肖战的博客-CSDN博客 二. uboot启动流程涉及的 _main汇编函数 经过之…

微信公众号

title: “微信公众号” createTime: 2022-01-05T10:14:2008:00 updateTime: 2022-01-05T10:14:2008:00 draft: false author: “name” tags: [“杂”] categories: [“software”] description: “测试的” 公众号发布文章 文章目录 title: "微信公众号" createTim…

数据结构与算法基础-(5)---栈的应用-(1)括号匹配

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

UG\NX二次开发 通过点云生成曲面 UF_MODL_create_surf_from_cloud

文章作者:里海 来源网站:《里海NX二次开发3000例专栏》 感谢粉丝订阅 感谢 Rlgun 订阅本专栏,非常感谢。 简介 有网友想做一个通过点云生成曲面的程序,我们也试一下 效果 代码 #include "me.hpp" /*HEAD CREATE_SURF_FROM_CLOUD CCC UFUN */

小谈设计模式(6)—依赖倒转原则

小谈设计模式&#xff08;6&#xff09;—依赖倒转原则 专栏介绍专栏地址专栏介绍 依赖倒转原则核心思想关键点分析abc 优缺点分析优点降低模块间的耦合度提高代码的可扩展性便于进行单元测试 缺点增加代码的复杂性需要额外的设计和开发工作 Java代码实现示例分析 总结 专栏介绍…

python编写修改sqlmap进行_WAF绕过

WAF绕过 文章目录 WAF绕过1 waf机制了解1.1 waf防火墙识别工具1.2 WAF机制及绕过方法总结: [绕waf参考总结地址](https://www.freebuf.com/articles/web/229982.html)1.3 绕过waf&#xff08;安全狗&#xff09;方式 2 绕过分析 -替换格式3 编写py脚本绕过安全狗3.1启动编好的脚…

Bug:elementUI样式不起作用、Vue引入组件报错not found等(Vue+ElementUI问题汇总)

前端问题合集&#xff1a;VueElementUI 1. Vue引用Element-UI时&#xff0c;组件无效果解决方案 前提&#xff1a; 已经安装好elementUI依赖 //安装依赖 npm install element-ui //main.js中导入依赖并在全局中使用 import ElementUI from element-ui Vue.use(ElementUI)如果此…

VBA技术资料MF62:创建形状添加文本及设置颜色

【分享成果&#xff0c;随喜正能量】须知往生净土&#xff0c;全仗信、愿。有信、愿&#xff0c;即未得三昧、未得一心不乱&#xff0c;亦可往生。且莫只以一心不乱&#xff0c;及得念佛三昧为志事&#xff0c;不复以信、愿、净念为事。。 我给VBA的定义&#xff1a;VBA是个人…

OpenWinding PMSM 开绕组永磁同步电机零序电流抑制以及无感控制

文章目录 前言仿真模型观测器速度观测位置观测电流波形A相电流零序电流电流FFT 转矩波形 前言 记录下最近开绕组电机的学习记录。 零序电流抑制&#xff0c;120解耦调制&#xff0c;基于零序电压的转子观测 仿真模型 观测器 速度观测 位置观测 电流波形 A相电流 零序电流 电…

新手怎么做小说推文和短剧推广怎么申请授权

新手想做小说推文和短剧推广可以通过“巨量推文”进行授权 只要你懂发短视频内容&#xff0c;会一点剪辑即可通过短剧推广和小说推文来获取收入 小说推文和短剧都分为cpa和cps模式 另短剧又cpm模式收入&#xff08;按照广告点击&#xff09; cpa为拉新类&#xff0c;cps为充…

1859. 将句子排序

目录 一、题目 二、代码 一、题目 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 二、代码 定义了一个vector<vector<string>> v(MAX);采用const string& word : v[k] word 就会依次取得 v[k] 中的每个元素&#xff08;v[k][0],…