C语言内存函数(21)
文章目录
- 前言
- 一、memcpy的使用和模拟实现
- 二、memmove的使用和模拟实现
- 三、memset函数的使用
- 四、memcmp函数的使用
- 总结
前言
正文开始,发车!
一、memcpy的使用和模拟实现
函数模型:void* memcpy(void* destination, const void* source, size_t num);
使用注意事项:
1.函数 memcpy 从 source 的位置开始向后复制 num 个字节的数据到 destination 指向的内存位置
2.这个函数在遇到 ‘\0’ 的时候并不会停下来,给多少就复制多少
3.如果 source 和 destination 有任何的重叠,复制的结果都是未定义的
// 使用举例
int main()
{ int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 }; int arr2[10] = {0}; //将arr1中的1 2 3 4 5,拷贝到arr2中 memcpy(arr2, arr1, 5*sizeof(int)); int i = 0; for (i = 0; i < 10; i++) { printf("%d ", arr2[i]); // 1 2 3 4 5 0 0 0 0 0} return 0;
}
我们来模拟实现一下 my_memcpy ,首先所接收的 dest 、src 都是不明确类型的,用 void* 接收,返回类型为 void*,且 src 并不希望被修改,可以加个 const 修饰
其实没那么复杂,我们有 num 个字节需要复制,那么直接循环 num 次就可以了,只是需要把 dest 和 src 强制转化成 char* 的类型就OK了

标红是因为什么原因?
原来,强制类型转化是临时的,下面两句各自加上就好了
dest = (char*)dest + 1;
src = (char*)src + 1;
这时候,我们再来回想一下为什么尽量要避免 dest 和 src 两者发生重叠
你脑海里想象一下 my_memcpy(arr1 + 2, arr1 + 1, 5 * sizeof(int)); 的过程,就明白了
下面是memcpy的完整模拟实现:
void* my_memcpy (void * dst, const void * src, size_t count )
{ void * ret = dst; assert(dst); assert(src); /* * copy from lower addresses to higher addresses */ while (count--) { *(char *)dst = *(char *)src; dst = (char *)dst + 1; src = (char *)src + 1; } return(ret);
}
二、memmove的使用和模拟实现
那怎么处理内存重叠的问题呢,那就用这个!
函数原型:void* memmove(void* destination, const void* source, size_t num);
使用注意事项:
1.可以把 memmove 当作可以处理重叠的 memcpy 吗? 可以!
我们来看看这个 memmove 为什么可以解决内存重叠情况下的复制:
当 src 在 dest 左边且发生重叠的时候,这时候如果从左往右复制,dest 所指向的 3 立马就被覆盖,等到 src 来复制的时候,已经只能复制 1 了,这不是我们想要的,于是,我们考虑从右向左复制,也就是 dest 的 7 被 5 覆盖 , 6 被 4 覆盖 … 3 被 1 覆盖

当 src 在 dest 右边且发生重叠的时候,这时候从右往左复制,又会发生上述的提前覆盖的情况,解决方法是什么?从左向右复制!

当 src 与 dest 不发生重叠的时候,从左向右 或者 从右向左 复制都没影响,所以我们想出一个总的复制方案
当 src < dest 的时候,从右向左复制
当 dest < src 的时候,从左向右复制
我们来思考一下 从右往左 复制该怎么实现,首先 dest 和 src 先跳到未部,注意要减一个1
dest = (char*)dest + num - 1;
src = (char*)src + num - 1;
接着开始往回复制,这与从左向右几乎等同,无非就是自加变为自减,所以,完整的 my_memmove 如下
void* my_memmove(void* dest, const void* src, size_t num)
{void* ret = dest;if (dest < src) {// 从左往右while (num--) {*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else {// 从右往左dest = (char*)dest + num - 1;src = (char*)src + num - 1;while (num--) {*(char*)dest = *(char*)src;dest = (char*)dest - 1;src = (char*)src - 1;}}return ret;
}
三、memset函数的使用
函数原型:void* memset(void* ptr, int value, size_t num);
memset是用来设置内存的,将内存中的值以字节为单位设置成想要的内容
// 使用实例
#include <stdio.h>
#include <string.h>
int main ()
{ char str[] = "hello world"; memset (str,'x',6); printf(str); // xxxxxxworldreturn 0;
}
请注意!memset在设置的时候,是以字节为单位来设置的
// 错误使用举例
int main()
{ int arr[10] = { 0 }; memset(arr, 1, 40); //errreturn 0;
}
因为它是以字节为单位来设置的,所以你可以想象,一个 int 有四个字节,每个字节都是1
也就是说,上述数组 arr 的每个元素都是 0x01010101,而不是我们想要的0x00000001
我们一般拿来清空、初始化数组或者结构体
四、memcmp函数的使用
函数原型:int memcmp(const void* ptr1, const void* ptr2, size_t num);
作用是比较从 ptr1 和 ptr2 指针指向的位置开始,向后的 num 个字节
// 使用实例
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[] = { 1,2,3,4,8 };int ret = memcmp(arr1, arr2, 16); // 0printf("%d\n", ret);ret = memcmp(arr1, arr2, 17); // -1printf("%d\n", ret);return 0;
}
至于原理,请调试并打开内存查看,就很清楚了

总结
我们在学习的时候应该带有自己的思考,比如上述 arr1 和 arr2 的图片可能有一个地方会引起你的注意
对于每个 int 的四个字节,数据低位同时也是存放在地址的低位
举例来说,假如把 int a = 1;存放在内存里面:
0x00000093F16FF6A8 :存放01
0x00000093F16FF6A9 :存放00
0x00000093F16FF6AA :存放00
0x00000093F16FF6AB :存放00
你可能跟我一样,对数据在内存中的存储由此产生了极大的疑问和兴趣,没关系,我们下篇文章开始介绍
相关文章:
C语言内存函数(21)
文章目录 前言一、memcpy的使用和模拟实现二、memmove的使用和模拟实现三、memset函数的使用四、memcmp函数的使用总结 前言 正文开始,发车! 一、memcpy的使用和模拟实现 函数模型:void* memcpy(void* destination, const void* source, size…...
三高基本概念之-并发和并行
并行和并发是计算机科学中两个重要但容易混淆的概念,它们之间的主要区别可以从以下几个方面进行阐述: 一、定义与含义 并行(Parallel):并行是指两个或多个事件在同一时刻发生,即这些事件在微观和宏观上都…...
宝塔面板FTP连接时“服务器发回了不可路由的地址。使用服务器地址代替。”
参考 https://blog.csdn.net/neizhiwang/article/details/106628899 错误描述 我得服务器是腾讯,然后使用宝塔建了个HTML网站,寻思用ftp上传,结果报错: 状态: 连接建立,等待欢迎消息... 状态: 初始化 TLS 中... 状…...
面试的一些小小经验
无论何时,找到合适的满意的工作(距离住处的地理位置,薪资,工作氛围)并不是一件容易的事情。个人能力与职位的适配性永远是有误差的客观存在。 十全十美难得,满足个人的个体化优先级才是客观的存在。 1.投简…...
IV转换放大器原理图及PCB设计分析
【前言】 今天给大家分享一下关于IV转换放大器的相关电路设计心得。IV转换使用的场合非常之多,尤其是电流型输出的传感器,比如光敏二极管、硅光电池等等,这些传感器输出的电流信号非常微弱,我们如果需要检测它们,首先得…...
【数学建模经验贴】一个研赛数模老手的经验
我(非C君,是一个朋友)参加了3次“深圳杯”数模,1次全国大学生数模,以及1次全国研究生数模,2016年参加了全国研究生数模的交流会,但没有参加过美赛,应该算是一个江湖老手了吧。下面内…...
vivo手机已删除的短信还能恢复吗?
虽然现在我们很少使用vivo手机的短信功能,但是我们偶尔还会通过vivo手机短信功能接收一些重要的信息。如果我们在清理垃圾短信的时候误删了vivo手机重要短信,该怎么恢复呢? 方法一:通过vivo云服务恢复 1、确保您已开启vivo云服务…...
[网络][CISCO]CISCO IOS升级
CISCO IOS升级-(转)2008-06-27 15:35IOS 升级 在介绍CISCO路由器IOS升级方法前,有必要对Cisco路由器的存储器的相关知识作以简单介绍。路由器与计算机相似,它也有内存和操作系统。在Cisco路由器中,其操作系统叫做互连…...
通过python提取PDF文件指定页的图片
整体思路 要从 PDF 文件中提取指定页和指定位置的图片,可以分几个步骤来实现: 1.1 准备所需工具与库 在 Python 中处理 PDF 和图像时,需要使用几个库: PyMuPDF (fitz):用于读取和处理 PDF 文件,可以精确…...
Leetcode Hot 100刷题记录 -Day12(轮转数组)
轮转数组 问题描述: 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4]解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向…...
GitHub每日最火火火项目(9.13)
以下是对这些项目的详细介绍: fishaudio 的 fish-speech: 基本信息:这是一种全新的语音技术解决方案,属于文本到语音(Text-to-Speech,TTS)技术范畴。技术特点: 多语言支持ÿ…...
力扣--649.Dota2参议院
Dota2 的世界里有两个阵营:Radiant(天辉)和 Dire(夜魇) Dota2 参议院由来自两派的参议员组成。现在参议院希望对一个 Dota2 游戏里的改变作出决定。他们以一个基于轮为过程的投票进行。在每一轮中,每一位参…...
vim 安装与配置教程(详细教程)
vim就是一个功能非常强大的文本编辑器,可以自己DIY的那种 ,不但可以写代码 ,还可编译 ,可以让你手不离键盘的完成鼠标的所有操作。 如果想要了解vim的的发展历史和详细解说,可以自行上网搜索,我主要是记录一…...
【WPF】Popup的使用
WPF(Windows Presentation Foundation)中的Popup控件用于创建弹出窗口,如工具提示、上下文菜单等。Popup控件本身并不直接显示任何内容,它需要一个子元素来显示实际的内容。 以下是一个简单的XAML示例,展示如何创建一…...
力扣刷题之2576.求出最多标记下标
题干描述 给你一个下标从 0 开始的整数数组 nums 。 一开始,所有下标都没有被标记。你可以执行以下操作任意次: 选择两个 互不相同且未标记 的下标 i 和 j ,满足 2 * nums[i] < nums[j] ,标记下标 i 和 j 。 请你执行上述操…...
黑马JavaWeb开发笔记16——请求(postman、简单参数、实体参数、@RequestParam映射)
文章目录 前言一、postman工具1. 引入2. 介绍3. 安装4. 使用 二、简单参数1. 原始方式(仅了解,以后的开发不会使用)2. SpringBoot方式3. 参数名不一致(RequestParam映射) 三、实体参数1. 简单实体对象2. 复杂实体对象 总结 前言 本篇文章是2…...
Corrupt block relative dba: 0x02c0b382 (file 11, block 45954)
接前面断电故障处理2:oracle数据库断电无法启动恢复-CSDN博客 DM00 started with pid145, OS id16516, job SYS.SYS_IMPORT_TABLE_01 2024-09-13T20:05:22.33130208:00 ADVISORY: Please collect redo for investigation of ORA-8103. Use command: ALTER SYSTE…...
二叉排序树在实际生活应用中作用
二叉排序树(Binary Search Tree, BST)在实际生活中有多种应用,主要用于需要快速查找、插入和删除操作的场景。以下是一些常见的应用领域和具体示例: 1.数据库索引 数据库系统中经常使用 BST 作为索引结构。例如,B-tr…...
单例模式的学习
示例: #ifndef TEST_H #define TEST_Hclass test { public:static test * GetINSTANCE();void print(); private:test(); };#endif // TEST_H#include "test.h" #include <QMutex> #include <QDebug> test::test() {}test *test::GetINSTANC…...
54 mysql 中各种 timeout - connect/wait/interactive/read/write_timeout
前言 在 mysql 的服务器配置中, 我们经常会使用到几个 timeout 诸如 connect_timeout, wait_timeout, interactive_timeout, read_timeout, write_timeout 等等 我们 这里来看一下 他们的具体的使用场景, 以及具体控制的相关信息 是什么 connect_timeout 这个是 客户端 和…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
