当前位置: 首页 > news >正文

内存函数详解

1. memcpy函数

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

1.1 函数的功能,使用与注意事项

1. memcpy函数的作用是内存拷贝,即将source指向的空间中的num个字节拷贝到destination指向的空间中去,然后返回destination原本的值。

#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[10] = { 0 };memcpy(arr2, arr1, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr2[i]);}return 0;
}

2. 该函数与strncpy不同之处在于,该函数在遇到'\0'时并不会停下来。

3. source与destination所指向的空间有任何重叠时,拷贝的结果都是未定义的。当需要进行这样的拷贝时,一般由下文会讲到的memmove函数完成。

对于第三点,给出以下示例

#include <stdio.h>
#include <string.h>int main()
{int arr[] = {1, 2, 3, 4, 5, 6, 7};memcpy(arr + 2, arr, 12);for(int i = 0; i < 7; i++){printf("%d ", arr[i]);}
}

此时,arr+2指向的空间与arr指向的空间是有重叠部分的,结果并不是我们所预期的“1 2 1 2 3 6 7”而是“1 2 1 2 1 6 7”(不同平台可能有不同的结果,vs2022和vscode输出的都是前者,因为他们对该函数的实现较为完善,与memmove的实现相似。按照C语言标准的规定,该函数的输出结果应该为后者)。

这是因为,当第一个整形拷贝完之后,source指向空间的前三个整形已经变成了“1 2 1”,继续拷贝下去,“1”就会被拷贝到原本“5”的位置上。

1.2 函数的模拟实现

void* my_memcpy(void* dest, const void* src, size_t num)
{assert(dest && src);void* ret = dest;while(num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}

2. memmove函数

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

2.1 函数的功能,使用与注意事项

基本与memcpy一样,但按照C语言标准规定,该函数才具备拷贝有重叠的空间的能力

2.2 函数的模拟实现

我们可以发现,之前memcpy无法做到重叠空间的拷贝的原因是,source指向空间中还未拷贝但预备拷贝的内容遭到了修改。

由于指向的空间有重叠的部分,所以source中一定会有内容被修改。但,问题是如何让这样的变化不影响拷贝呢?

当然是,确保重叠部分的空间都是在被拷贝之后再被修改。

当destination指向位置在source指向位置之后时,重叠部分位于source的后端,那么我们就应该从后端开始向前拷贝;

当destination指向位置在source指向位置之前时,重叠部分位于source的前端,那么我们就应该从前端开始向后拷贝。

void* my_memmove(void* dest, const void* src, size_t num)
{assert(dest && src);void* ret = dest;//dest在前,从前向后拷//dest在后,从后向前拷if(dest < src){while(num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else{while(num--){*((char*)dest + num) = *((char*)src + num);}}return ret;
}

3. memset函数

void * memset ( void * ptr, int value, size_t num );

3.1 函数的功能,使用与注意事项

memset函数的作用是设置内存,即将ptr指向空间中的num个字节的值设置为value,然后返回ptr原本的值。

#include <stdio.h>
#include <string.h>int main ()
{char str[] = "hello world";memset (str,'x',6);printf("%S\n", str);return 0;
}

3.2 函数的模拟实现

void* my_memset(void* ptr, int value, size_t num)
{assert(ptr);while(num--){*((char*)ptr + num) = value;}return ptr;
}

4. memcmp函数

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

4.1 函数的功能,使用与注意事项

依次比较ptr1与ptr2指向空间中num个字节的值的大小。

若ptr1较大,返回大于零的数;

若ptr2较大,返回小于零的数;

若相同,则返回零。

该函数似乎意义不大,用到的地方很少,毕竟比较字节的大小似乎没有什么意义。

#include <stdio.h>
#include <string.h>int main()
{char buffer1[] = "DWgaOtP12df0";char buffer2[] = "DWGAOTP12DF0";int n;n = memcmp(buffer1, buffer2, sizeof(buffer1));if (n > 0) printf("'%s' is greater than '%s'.\n", buffer1, buffer2);else if (n < 0) printf("'%s' is less than '%s'.\n", buffer1, buffer2);elseprintf("'%s' is the same as '%s'.\n", buffer1, buffer2);return 0;
}

4.2 函数的模拟实现

int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{assert(ptr1 && ptr2);while(*(char*)ptr1 == *(char*)ptr2 && num--){ptr1++;ptr2++;}return *(char*)ptr1 - *(char*)ptr2;
}

相关文章:

内存函数详解

1. memcpy函数 void * memcpy ( void * destination, const void * source, size_t num ); 1.1 函数的功能&#xff0c;使用与注意事项 1. memcpy函数的作用是内存拷贝&#xff0c;即将source指向的空间中的num个字节拷贝到destination指向的空间中去&#xff0c;然后返回de…...

事务(transaction)

事务&#xff0c;什么是事务&#xff0c;事务就是由单独单元的一个或多个sql语句组成&#xff0c;在这个单元中&#xff0c;每个sql语句都是相互依赖的。而整个单独单元是作为一个不可分割的整体存在&#xff0c;类似于物理当中的原子&#xff08;一种不可分割的最小单位&#…...

Linux之cd、pwd、mkdir 命令

cd命令&#xff0c;切换目录 1&#xff09;当Linux终端&#xff08;命令行&#xff09;打开的时候&#xff0c;会默认以用户的HOME目录作为当前的工作目录。 2&#xff09;我们可以通过cd命令&#xff0c;更改当前所在的工作目录。 3&#xff09;cd命令来自英文&#xff1a;C…...

【python高级编程教程】笔记(python教程、python进阶)第三节:(1)多态与鸭子类型(Polymorphism and Duck Typing)

参考文章1&#xff1a;【比刷剧还爽】清华大佬耗时128小时讲完的Python高级教程&#xff01;全套200集&#xff01;学不会退出IT界&#xff01; 参考文章2&#xff1a;清华教授大力打造的Python高级核心技术&#xff01;整整100集&#xff0c;强烈建议学习&#xff08;Python3…...

学习JAVA的第十五天(基础)

目录 数据结构 二叉树 二叉查找树 平衡二叉树 红黑树 Set系列集合 HashSet集合 LinkedHashSet集合 TreeSet集合 前言&#xff1a;学习JAVA的第十四天&#xff08;基础&#xff09;-CSDN博客 数据结构 二叉树 元素&#xff1a;结点&am…...

LVS四层负载均衡集群

简介 LVS&#xff08;Linux Virtual Server&#xff09;即Linux虚拟服务器&#xff0c;是由章文嵩博士主导的开源负载均衡项目&#xff0c;目前LVS已经被集成到Linux内核模块中。该项目在Linux内核中实现了基于IP的数据请求负载均衡调度方案&#xff0c;终端互联网用户从外部访…...

【pyinstaller打包记录】程序使用多进程,打包后,程序陷入死循环

简介 PyInstaller 是一个用于将 Python 程序打包成可执行文件&#xff08;可执行程序&#xff09;的工具。它能够将 Python 代码和其相关的依赖项&#xff08;包括 Python 解释器、依赖的模块、库文件等&#xff09;打包成一个独立的可执行文件&#xff0c;方便在不同环境中运行…...

MAC | linux | SSH 密钥验证

SSH密钥登陆过程 客户端通过ssh-keygen生成自己的公钥和私钥。手动将客户端的公钥放入远程服务器的指定位置。客户端向服务器发起 SSH 登录的请求。服务器收到用户 SSH 登录的请求&#xff0c;发送一些随机数据给用户&#xff0c;要求用户证明自己的身份。客户端收到服务器发来…...

【AI Agent系列】【MetaGPT多智能体学习】3. 开发一个简单的多智能体系统,兼看MetaGPT多智能体运行机制

本系列文章跟随《MetaGPT多智能体课程》&#xff08;https://github.com/datawhalechina/hugging-multi-agent&#xff09;&#xff0c;深入理解并实践多智能体系统的开发。 本文为该课程的第四章&#xff08;多智能体开发&#xff09;的第一篇笔记。主要记录下多智能体的运行…...

机器学习-面经(part7、无监督学习)

机器学习面经系列的其他部分如下所示&#xff1a; 机器学习-面经&#xff08;part1&#xff09; 机器学习-面经(part2)-交叉验证、超参数优化、评价指标等内容 机器学习-面经(part3)-正则化、特征工程面试问题与解答合集机器学习-面经(part4)-决策树共5000字的面试问题与解答…...

teknoparrot命令行启动游戏

官方github cd 到teknoparrot解压目录 cd /d E:\mn\TeknoParrot2_cp1\GameProfiles启动游戏 TeknoParrotUi.exe --profile游戏配置文件游戏配置文件位置/UserProfiles,如果UserProfiles文件夹里没有那就在/GameProfiles,在配置文件里将游戏路径加入之间,或者打开模拟器设置 …...

停止Tomcat服务的方式

运行脚本文件停止 运行Tomcat的bin目录中提供的停止服务的脚本文件 关闭命令 # sh方式 sh shutdown.sh# ./方式 ./shutdown.sh操作步骤 运行结束进程停止 查看Tomcat进程&#xff0c;获得进程id kill进程命令 # 执行命令结束进程 kill -9 65358 操作步骤 注意 kill命令是…...

多线程相关面试题(2024大厂高频面试题系列)

1、聊一下并行和并发有什么区别&#xff1f; 并发是同一时间应对多件事情的能力&#xff0c;多个线程轮流使用一个或多个CPU 并行是同一时间动手做多件事情的能力&#xff0c;4核CPU同时执行4个线程 2、说一下线程和进程的区别&#xff1f; 进程是正在运行程序的实例&#xff…...

mysql 时间精度问题

timestamp到2038年&#xff0c;还有14年时间&#xff0c;一个系统如果能活到那一刻也是相当不错了。 这里先看一下个datetime的问题,下面的插入数据的时间戳是2024-03-06 21:20:50.839 INSERT INTO psi_io_balance ( id, as_id, bill_date, order_id, busi_type, direction, c…...

基于python的爬虫原理和管理系统实现(代码下载)

Python实现爬虫的原理如下&#xff1a; 发送请求&#xff1a;使用Python中的库&#xff0c;如Requests或urllib&#xff0c;向目标网站发送HTTP请求&#xff0c;获取网页的内容。 解析网页&#xff1a;使用Python中的库&#xff0c;如BeautifulSoup或lxml&#xff0c;对获取的…...

IOS 设置UIViewController为背景半透明浮层弹窗,查看富文本图片详情

使用场景&#xff1a;UIViewController1 打开 UIViewController2&#xff08;背景半透明弹窗&#xff09; 案例&#xff1a;打开富文本网页<img>图片的url查看图片详情 WKWebView WKNavigationDelegate代理方法设置js代码点击事件 ///注册添加图片标签点击js方法 - …...

网络层介绍

网络层是OSI模型中的第三层&#xff0c;也称为网络协议层。它主要负责在源主机和目标主机之间提供数据通信的路径选择和控制。网络层通过使用源和目标主机的网络地址来实现数据包的路由和转发。 以下是网络层的一些主要功能&#xff1a; 路由选择&#xff1a;网络层使用路由选…...

springboot/ssm酒店客房管理系统Java在线酒店预约预定平台web

springboot/ssm酒店客房管理系统Java在线酒店预约预定平台web 基于springboot(可改ssm)vue项目 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;…...

分布式测试插件 pytest-xdist 使用详解

使用背景&#xff1a; 大型测试套件&#xff1a;当你的测试套件非常庞大&#xff0c;包含了大量的测试用例时&#xff0c;pytest-xdist可以通过并行执行来加速整体的测试过程。它利用多个进程或计算机的计算资源&#xff0c;可以显著减少测试执行的时间。高计算资源需求&#…...

【S32K3 MCAL配置】-1.1-GPIO配置及其应用-点亮LED灯(基于MCAL)

目录(共13页精讲,手把手教你S32K3从入门到精通) 实现的架构:基于MCAL层 前期准备工作: 1 创建一个FREERTOS工程...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...