《内存函数》

内存函数

1. memcpy函数

(1)介绍

在这里插入图片描述
这里通过memcpy的定义我们可以看这个函数包含三个参数,destination就是拷贝的目的地,source就是拷贝的源头,num就是拷贝的个数。

(2)使用

在这里插入图片描述

  1. 这里要包含头文件string.h
  2. 这里的个数最好写成sizeof(类型)* 个数的形式,因为你拷贝什么类型未定

(3)memcpy 函数模拟实现

在这里插入图片描述
思路整理: 通过对memcpy的学习,我们知道了这是一个用来拷贝数据的函数,并且它本身并不care它要拷贝的数据是什么类型的,所以这里我们传参的时候就要写成void* 的指针,和原函数保持一致,由于我们要用这个函数来实现所有类型数据的拷贝,所以用char*类型的指针来逐个字节进行交换最合适不过了,但void* 的指针不能直接进行解引用,要进行强转,然后在逐个字节进行交换时,两个指针要往后走,至于走到哪,这里就拿while循环来判断,将num作为循环判断条件,当num为0时交换完成,循环正好停止,但是因为强转类型是是临时的,所以这里直接让指针++就不行,还要再次进行强转才可以,这里是比较容易忽视的一个点。并且这个函数还要返回目的地的地址,并且是void*类型的,但是直接在结尾返回dest是有问题的,因为在进行了一系列循环后,指针早就跑远了,这时候我们就可以在开头就先把这个地址传给另一个指针ret,最后在结尾返回指针ret就可以了,这时候这个函数就比较完善了,但因为这里用到了指针,所以在使用之前其实可以先判断一下是否为空指针,这时候就用到了assert,加上这个的话函数就更加健壮了。

(4)局限性

其实C语言中规定memcpy函数不用来拷贝重叠内存,但我们还是来测试一下
首先我们用自己模拟的my_memcpy来测试一下

在这里插入图片描述
显然这里我们可以发现用我们自己模拟的my_memcpy函数拷贝重叠内存时发生了错误,我们可以借助下图来进行理解
在这里插入图片描述
我们通过逐个字节来交换来进行拷贝,但比如这里的源头在该取3来进行交换时,这时候其实3已经被1给覆盖了,也就是说这时候你取出的不是3,而是1,所以这时候就出错了啊。

既然我们自己模拟的my_memcpy不能完成这个任务,那么库函数中的memcpy应该也不行吧,下面我们来试一下

在这里插入图片描述
到这里有些同学可能就坐不住了,这memcpy不是说不能拷贝重叠内存的吗?这里为什么还是可以啊,其实不然,这只是在部分编译器中可以实现,但你不能保证它在任何情况下都可以做得到的,并且我们有专门的函数来实现这个功能,所以不建议用memcpy这样干。

2.memmove函数

(1) 介绍

在这里插入图片描述
这里通过memmove的定义我们可以发现这个函数也是有三个参数,包括目的地、源头、拷贝个数

(2)使用

在这里插入图片描述

这里我们看到memmove函数不仅可以实现重叠内存的拷贝,而且也可以实现不相关两组数据的拷贝。

(3)memmove函数模拟实现

在这里插入图片描述
思路整理: 通过对memmove函数的学习,我们发现这个函数是既可以实现重叠内存的拷贝,也可以实现不相关内存的拷贝,这时候我们在实现这个函数的时候就需要分情况来思考了,我们通过下面这个图来理解:
在这里插入图片描述

  1. 情况1的时候如果还是先从源头开始拷贝的话就会出现一种现象:在拷贝3的时候,这个3已经被1给覆盖住了,你拿到的不是3而是1,这就出错了啊,所以这个时候我们就需要从末尾开始拷贝,从源头的末尾开始拷贝,依次放到目的地的末尾,这样就可以正确拷贝了
  2. 情况2的话是目的地在在源头左边,这个时候就可以从源头开头依次进行拷贝,也就是和上面的my_memcpy道理一样。
    3.情况三不属于重叠内存的拷贝,无论是从左还是从右拷贝都可以
  3. 既然这样话,我们可以以dest和src的位置来划定情况,当dest在src左边时从左开始拷贝,其他两种情况从右开始拷贝。

这里其实还需要进行解释的一点是在从右开始拷贝的时候怎么找到src和dest的末尾,这里我们通过(char*)dest + num (char*)src + num 分别找到了destsrc的末尾,接着我们通过while循环,并且以num-- 作为循环判断条件,这时候随着num的变化,指向destsrc的指针也跟着移动,从右向左进行交换,当num为0时,交换完成,循环停止。

(4)memcpy和对比memmove对比

综上所述:memmove函数的作用>> memcpy的作用,memcpy能做的memmove可以做,memcpy做不了的memmove也能做。

3. memset函数

(1)介绍:

在这里插入图片描述
通过memset的定义我们可以看到这个函数包含了三个参数
在这里插入图片描述
一般情况下这个函数可以用来内存的初始化、清空数组、给特殊值

(2)使用

在这里插入图片描述

这个函数比较简单就不再过多介绍。

4. memcmp函数

(1)介绍

在这里插入图片描述
在这里插入图片描述

(2)使用

在这里插入图片描述
注意这里比较的是内存中的大小。

5.总结

这期我们主要学习了memcpy函数、memmove函数及两个函数的模拟实现、memset函数和memcmp函数。这期中比较难一点理解的就是memmove函数的模拟实现,大家可以反复翻看,加深理解,注意体会其中的思想。

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

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

相关文章

不泄密的安全远程控制软件需要哪些技术

在数字化浪潮中,远程控制软件已不再是简单的辅助工具,而是成为企业运作和日常工作中不可或缺的一部分。随着远程办公模式的广泛采纳,这些软件提供了一种既安全又高效的途径来管理和访问远端系统。无论是在家办公、技术支持还是远程教育&#…

Pycharm打开终端时报错:Cannot open Local,Failed to start[powershell.exe]

问题如下: 解决办法: 修改设置中的shell path路径 英文版pycharm:file -> settings -> Tools -> Terminal -> Shell path 中文版pycharm:文件 -> 设置 -> 工具 -> 终端 -> Shell路径 将Shell路径不全 …

15分钟学 Go 第 51 天 :通用库与工具使用

第51天:通用库与工具使用 一、学习目标 类别工具/库用途命令行工具cobra构建命令行应用JSON处理gjson高效JSON解析HTTP客户端restyHTTP请求处理日期处理carbon时间日期操作配置管理viper配置文件处理 二、详细实现 让我们通过具体示例来学习这些库的使用&#x…

基于微信小程序的乡村研学游平台设计与实现,LW+源码+讲解

摘 要 信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自…

VLC-QT----Linux编译并运行示例

linux:ubuntu 16.04 qt:5.13.2 总体安装步骤 下载安装,编译 下载源码仓库,下载cmake,新建一个build文件夹,cd进去,执行代码 cmake .. -DCMAKE_BUILD_TYPEDebug 遇到报错,没有qt5Coreconfig,运行 sudo apt-get install qtdeclarative5-dev进行安装 遇到报错 Could not fi…

机器学习:XGBoost模型——高效且强大的树形模型

XGBoost(Extreme Gradient Boosting,极端梯度提升树)是一种强大的梯度提升算法,在现实中被广泛用于分类和回归任务。它通过集成多个简单的基学习器(通常是决策树)来构建一个强大的预测模型。 基本原理步骤…

爬虫开发工具与环境搭建——开发工具介绍

第二章:爬虫开发工具与环境搭建 第一节 开发工具介绍 爬虫开发需要一些合适的工具和框架来高效地抓取网页数据。在这节中,我们将介绍常用的开发工具,帮助开发者快速搭建爬虫开发环境。 1. Python与爬虫框架选择 Python因其简洁、易学的语法…

python高级之面向对象编程

一、面向过程与面向对象 面向过程和面向对象都是一种编程方式,只不过再设计上有区别。 1、面向过程pop: 举例:孩子上学 1. 妈妈起床 2. 妈妈洗漱 3. 妈妈做饭 4. 妈妈把孩子叫起来 5. 孩子起床 6. 孩子洗漱 7. 孩子吃饭 8. 妈妈给孩子送学校…

通过Docker实现openGauss的快速容器化安装

容器安装 本章节主要介绍通过 Docker 安装 openGauss,方便 DevOps 用户的安装、配置和环境设置。 支持的架构和操作系统版本 x86-64 CentOS 7.6 ARM64 openEuler 20.03 LTS 配置准备 使用 buildDockerImage.sh 脚本构建 docker 镜像,buildDockerIm…

康谋分享 | 确保AD/ADAS系统的安全:避免数据泛滥的关键

为确保AD/ADAS系统的安全性,各大车企通常需要收集、处理和分析来自于摄像头、激光雷达等传感器的数据,以找出提高系统安全性和性能的方法。然而在数据收集过程中,不可避免地会出现大量无价值数据,造成数据泛滥的情况,进…

电工电子原理笔记

这一篇手记会记录我硬件开发过程中遇到的一些底层电学原理,并且结合实际场景作为“例题”(出于篇幅和保密考虑会进行部分简化)。 叠加定理 基本介绍 在线性电路中,任一支路的电流(或电压)可以看成是电路…

【赵渝强老师】MySQL InnoDB的段、区和页

MySQL的InnoDB存储引擎的逻辑存储结构和Oracle大致相同,所有数据都被逻辑地存放在一个空间中,我们称之为表空间(tablespace)。表空间又由段(segment)、区(extent)、页(pa…

Python 继承笔记

知识点: 1.has a 一个类中使用了另外一种自定义类的类型 student 使用computer book 2.类型 系统类型 str,int,float,list,tuple,dic,set 自定义类型 算是自定义的类,都可以将其当成一种类型 student是一种类型 sStudent() s是Student的类型 class Stud…

Vue3 -- 项目配置之husky【企业级项目配置保姆级教程4】

引言: eslint:代码规范校验prettier:代码格式化stylelint:CSS代码校验 上述三篇文章集成配置完成代码校验工具,当时需要每次手动的去执行命令才会格式化我们的代码。。如果有人没有格式化就提交了远程仓库&#xff0…

万字长文分析函数式编程

目录 一.认识函数式编程 一、函数式编程的定义 二、函数式编程的思想 三、函数式编程的特点 四、函数式编程的应用 二.Lambda表达式 三.Stream流 3.1 创建流对象 3.2 注意事项 3.3 Stream流的中间操作 filter map distinct sorted limit skip flatMap 3.4 St…

移植 AWTK 到 纯血鸿蒙 (HarmonyOS NEXT) 系统 (8) - 原生输入法

AWTK 在嵌入式平台使用内置的输入法,在移动设备上使用系统的原生输入法。在 AWTK-Android 和 AWTK-IOS 中,使用的是 SDL 封装之后的系统原生输入法。在 AWTK-HarmonyOS 中,要使用系统的原生输入法。需要实现 input_method 接口: 1…

【解决】Layout 下创建槽位后,执行 Image 同步槽位位置后表现错误的问题。

开发平台:Unity 6.0 编程语言:CSharp 编程平台:Visual Studio 2022   一、问题背景 | 开发库存系统 图1 位置同步失败问题 图2 位置正常同步效果表现 黑框 作用于 UnityEngine.UI.GridLayoutGruop,形成 4x6 布局,如…

【Jenkins实战】Windows安装服务启动失败

写此篇短文,望告诫后人。 如果你之前装过Jenkins,出于换域账号/本地帐号的原因想重新安装,你大概率会遇上一次Jenkins服务启动失败提示: Jenkins failed to start - Verify that you have sufficient privileges to start system…

免费,WPS Office教育考试专用版

WPS Office教育考试专用版,不仅满足了考试需求,更为教育信息化注入新动力。 https://pan.quark.cn/s/609ef85ae6d4

94个属于一区且接受医工交叉领域投稿的期刊汇总|个人观点·24-11-13

小罗碎碎念 继汇总病理AI的基础模型、病理组学&影像组学的公开数据集以后,我们再来盘一盘医工交叉领域有哪些热门期刊可以投稿。我会分区进行介绍,每个区则会进一步划分学科种类,方便大家选择适合自己的投稿期刊。 这期推文先分享大类属…