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

目录

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 10printf("\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.xdnf.cn/news/145346.html

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

相关文章

整型提升——(巩固提高——字符截取oneNote笔记详解)

文章目录 前言一、整型提升是什么&#xff1f;二、详细图解1.图解展示 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 整型提升是数据存储的重要题型&#xff0c;也是计算机组成原理的核心知识点。学习c语言进阶的时候,了解内存中数据怎么存&#…

孤举者难起,众行者易趋,openGauss 5.1.0版本正式发布!

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

华为云云耀云服务器L实例评测|云耀云服务器L实例搭建个人镜像站

华为云云耀云服务器L实例评测&#xff5c;云耀云服务器L实例搭建个人镜像站 一、云耀云服务器L实例介绍1.1 云耀云服务器L实例简介1.2 云耀云服务器L实例特点 二、Apache介绍2.1 Apache简介2.2 Apache特点 三、本次实践介绍3.1 本次实践简介3.2 本次环境规划 四、远程登录华为云…

SpringCloud Alibaba 入门到精通 - Sentinel

SpringCloud Alibaba 入门到精通 - Sentinel 一、基础结构搭建1.父工程创建2.子工程创建 二、Sentinel的整合SpringCloud1.微服务可能存在的问题2.SpringCloud集成Sentinel搭建Dashboard3 SpringCloud 整合Sentinel 三、服务降级1 服务降级-Sentinel2 Sentinel 整合 OpenFeign3…

【深度学习实验】卷积神经网络(三):自定义二维卷积层:步长、填充、输入输出通道

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入必要的工具包 1. 步长、填充 a. 二维互相关运算&#xff08;corr2d&#xff09; b. 二维卷积层类&#xff08;Conv2D&#xff09; c. 模型测试 d. 代码整合 2. 输入输出通道 a…

Arcgis克里金插值报错:ERROR 999999: 执行函数时出错。 表名无效。 空间参考不存在。 ERROR 010429: GRID IO 中存在错误

ERROR 999999: 执行函数时出错。 问题描述 表名无效。 空间参考不存在。 ERROR 010429: GRID IO 中存在错误: WindowSetLyr: Window cell size does not match layer cell size. name: c:\users\lenovo\appdata\local\temp\arc2f89\t_t164, adepth: 32, type: 1, iomode: 6, …

智能合约漏洞,Dyna 事件分析

智能合约漏洞&#xff0c;Dyna 事件分析 1. 漏洞简介 https://twitter.com/BlockSecTeam/status/1628319536117153794 https://twitter.com/BeosinAlert/status/1628301635834486784 2. 相关地址或交易 攻击交易 1&#xff1a; https://bscscan.com/tx/0x7fa89d869fd1b89e…

算法通过村第十一关-位运算|青铜笔记|初始位运算

文章目录 前言1. 数字在计算中的表示拓展&#xff1a;为什么要有原码、反码和补码? 2. 位运算规则2.1 与、或、异或和取反2.2 位移运算2.3 位移运算和乘除的关系2.4 位运算的常用技巧 总结 前言 提示&#xff1a;我的父亲从我出生起便认识我&#xff0c;可他对我的了解却那么少…

西北主要河流水系(绿洲)流域(山区)及高程分类数据集(一)

最近收集整理的了西北地区主要河流水系&#xff08;绿洲&#xff09;流域&#xff08;山区&#xff09;及高程分类数据&#xff0c;&#xff0c;本次主要是新疆的河流水系&#xff08;绿洲&#xff09;流域&#xff08;山区&#xff09;及高程分类数据&#xff08;矢量&#xf…

ThemeForest – Canvas 7.2.0 – 多用途 HTML5 模板

ThemeForest 上的 HTML 网站模板受到全球数百万客户的喜爱。与包含网站所有页面并允许您在 WP 仪表板中自定义字体和样式的 WordPress 主题不同&#xff0c;这些设计模板是用 HTML 构建的。您可以在 HTML 编辑器中编辑模板&#xff0c;但不能在 WordPress 上编辑模板&#xff0…

机器人过程自动化(RPA)入门 7. 处理用户事件和助手机器人

在UiPath中,有两种类型的Robot用于自动化任何流程。一个是后台机器人,它在后台工作。它独立工作,这意味着它不需要用户的输入或任何用户交互。另一个是前台机器人,也被称为助理机器人。 本章介绍前台机器人。在这里,我们将了解自动化过程中通过简单按键、单击鼠标等触发事…

【Vue】数据监视输入绑定

hello&#xff0c;我是小索奇&#xff0c;精心制作的Vue系列持续发放&#xff0c;涵盖大量的经验和示例&#xff0c;如有需要&#xff0c;可以收藏哈 本章给大家讲解的是数据监视&#xff0c;前面的章节已经更新完毕&#xff0c;后面的章节持续输出&#xff0c;有任何问题都可以…

Pikachu-xxe (xml外部实体注入漏洞)过关笔记

Pikachu-xxe过关笔记 有回显探测是否有回显file:///协议查看本地系统文件php://协议查看php源代码&#xff08;无法查看当前网页代码&#xff0c;只能看别的&#xff09;http://协议爆破开放端口&#xff08;两者的加载时间不同&#xff09; 无回显第一步第二步第三步 运行结果…

【面试题】2023前端面试真题之JS篇

前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 表妹一键制作自己的五星红旗国庆头像&#xff0c;超好看 世界上只有一种真正的英雄主义&#xff0c;那就是看清生活的真相之后&#xff0c;依然热爱生活。…

1.项目创建与角色移动

目录 1.创建项目 2.导入素材 3.搭建场景 4.创建玩家 1.创建项目 2.导入素材 3D GUNS | Guns Pack | 3D 武器 | Unity Asset Storehttps://assetstore.unity.com/packages/3d/props/weapons/3d-guns-guns-pack-228975 Prototyping Pack (Free) | 3D | Unity Asset S…

外包公司干了2个月,技术倒退两年...

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入杭州某软件公司&#xff0c;干了接近3年的功能测试&#xff0c;今年8月份&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了三年的功能测试…

87、Redis 的 value 所支持的数据类型(String、List、Set、Zset、Hash)---->List相关命令

本次讲解要点&#xff1a; List相关命令&#xff1a;是指value中的数据类型 启动redis服务器&#xff1a; 打开小黑窗&#xff1a; C:\Users\JH>e: E:>cd E:\install\Redis6.0\Redis-x64-6.0.14\bin E:\install\Redis6.0\Redis-x64-6.0.14\bin>redis-server.exe redi…

R语言绘制环状柱状堆积图+分组+显著性

无叠加、显著性的代码&#xff1a; #设置工作环境 rm(listls()) setwd("D:/Desktop/0000/code-main/条形图")#加载R包 library(ggplot2) # Create Elegant Data Visualisations Using the Grammar of Graphics library(tidyverse) # Easily Install and Load the Ti…

HarmonyOS/OpenHarmony原生应用-ArkTS万能卡片组件Badge

可以附加在单个组件上用于信息标记的容器组件。该组件从API Version 7开始支持。 支持单个子组件。子组件类型&#xff1a;系统组件和自定义组件&#xff0c;支持渲染控制类型&#xff08;if/else、ForEach和LazyForEach&#xff09;。 一、接口 方法1&#xff1a; Badge(value…

【Python实战】-- 按条件提取所有目录下所有Excel文件指定行数据

系列文章目录 文章目录 系列文章目录前言一、背景二、使用步骤1.源码总结前言 一、背景 有多个目录,每个目录下有若干Excel文件,我们要提取每个Excel里面指定的行数据: 目录如下: 注:目录数量、名称不限,其中文件数量、名称不限 二、使用步骤 1.源码 解释: 每个文件…