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

【C语言】12.C语言内存函数

文章目录

  • 1.memcpy使用和模拟实现
  • 2.memmove使用和模拟实现
  • 3.memset函数的使用
  • 4.memcmp函数的使用


memcpy:内存拷贝

memmove:内存移动

memset:内存设置

memcmp:内存比较

1.memcpy使用和模拟实现

memcpy:内存拷贝

void * memcpy ( void * destination, const void * source, size_t num );目标空间的地址          源空间的地址        被拷贝的字节个数
返回的是目标空间的起始地址
void*指针接收任意参数的地址

函数memcpysource的位置开始向后复制num个字节的数据到destination指向的内存位置。

这个函数在遇到 ‘\0’ 的时候并不会停下来。

如果sourcedestination有任何的重叠,复制的结果都是未定义的。

#include <stdio.h>
#include <assert.h>void* my_memcpy(void* dest, const void* src, size_t num) {int i = 0;void* ret = dest;assert(src && dest);while (num--) {*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}int main() {int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };//将arr1中的34567拷贝到arr2中my_memcpy(arr2, arr1 + 2, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr2[i]);}return 0;
}

打印:

3 4 5 6 7 0 0 0 0 0

注意:对于重叠的内存,交给memmove来处理。

重叠的意思就是:

my_memcpy(arr1 + 2, arr1, 20);

比如你想把arr数组里的某些数用arr数组的某些数替换,这样会出问题。

例如:

void* my_memcpy(void* dest, const void* src, size_t num) {int i = 0;void* ret = dest;assert(src && dest);while (num--) {*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}int main() {int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//我们的想法是:将arr1中的12345拷贝到arr1中原来34567的地方,将原来的覆盖my_memcpy(arr1 + 2, arr1, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}

打印:

1 2 1 2 1 2 1 8 9 10

打印这个玩意儿?怎么和猜的不一样呢?

1 2 3 4 5 6 7 8 9 10

程序里先把1替换了3

1 2 1 4 5 6 7 8 9 10

然后2替换了4

1 2 1 2 5 6 7 8 9 10

然后原来3位置的1替换了5

1 2 1 2 1 6 7 8 9 10

然后原来4位置的2替换了6

1 2 1 2 1 2 7 8 9 10

然后原来5位置的1替换了7

1 2 1 2 1 2 1 8 9 10

memcpy函数不负责重叠内存的拷贝,只负责不重叠的内存,非要使用,结果就是未定义的。

不过说是这么说,有些时候memcpy也能实现重叠内存的拷贝。我们可以认为memcpy实现的拷贝不一定都对。所以重叠就用memmove函数。

memmove函数来处理重叠内存的拷贝。


2.memmove使用和模拟实现

memmove:内存移动

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

memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。

如果源空间和目标空间出现重叠,就得使用memmove函数处理。

#include <string.h>int main() {int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//将arr1中的12345拷贝到arr1中原来34567的地方,将原来的覆盖memmove(arr1 + 2, arr1, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}

打印:

1 2 1 2 3 4 5 8 9 10

在这里插入图片描述

这个函数实际上就是实现src拷贝到dest。

如果是上面一种情况的话,我们可以先把3给1,然后把4给2,然后把5给3…这样就可以实现重叠内存的处理。(从前向后)

如果是中间一种情况的话,我们可以先把7给9,然后把6给8,然后把5给7…这样就可以实现重叠内存的处理。(从后向前)

如果是下面一种情况的话,我们可以按顺序把3给8,把4给9,把5给10…这样就可以实现重叠内存的处理。(从后向前)

在这里插入图片描述

两个紫色竖线表示的位置分别为src的起始位置和结束位置。

这两根紫色竖线把情况分成了三种。

第一种情况是(从前向后)

第二种情况是(从后向前)

模拟实现:

void* my_memmove(void* dest, const void* src, size_t num) {void* ret = dest;assert(src && 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;
}int main() {int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//将arr1中的12345拷贝到arr1中原来34567的地方,将原来的覆盖my_memmove(arr1 + 2, arr1, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}

打印:

1 2 1 2 3 4 5 8 9 10

3.memset函数的使用

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);return 0;
}

打印:

xxxxxxworld

4.memcmp函数的使用

memcmp:内存比较

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

比较从ptr1和ptr2指针指向的位置开始,向后的num个字节

返回值如下:

在这里插入图片描述


#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5 };//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00int arr2[] = { 1,2,3,6,5 };//01 00 00 00 02 00 00 00 03 00 00 00 06 00 00 00 05 00 00 00int ret = memcmp(arr1, arr2, 12);printf("%d\n", ret);return 0;
}

打印:

0

因为前12个字节一样


#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5 };//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00int arr2[] = { 1,2,3,6,5 };//01 00 00 00 02 00 00 00 03 00 00 00 06 00 00 00 05 00 00 00int ret = memcmp(arr1, arr2, 13);printf("%d\n", ret);return 0;
}

打印:

-1

因为第13个字节不一样

相关文章:

【C语言】12.C语言内存函数

文章目录 1.memcpy使用和模拟实现2.memmove使用和模拟实现3.memset函数的使用4.memcmp函数的使用 memcpy&#xff1a;内存拷贝 memmove&#xff1a;内存移动 memset&#xff1a;内存设置 memcmp&#xff1a;内存比较 1.memcpy使用和模拟实现 memcpy&#xff1a;内存拷贝 void…...

Django:如何将多个数据表内容合在一起返回响应

一.概要 Django写后端返回响应时&#xff0c;通常需要返回的可能不是一个数据表的内容&#xff0c;还包括了这个数据表的外键所关联的其他表的一些字段&#xff0c;那该如何做才能把他们放在一起返回响应呢&#xff1f; 二.处理方法 在这里我有三个数据表 第一个是航空订单&…...

棱镜七彩荣获CNNVD两项大奖,专业能力与贡献再获认可!

6月18日&#xff0c;国家信息安全漏洞库&#xff08;CNNVD&#xff09;2023年度工作总结暨优秀表彰大会在中国信息安全测评中心成功举办。棱镜七彩凭借在漏洞方面的突出贡献和出色表现&#xff0c;被授予“2023年度优秀技术支撑单位”与“2023年度最佳新秀奖”。 优秀技术支撑单…...

uni-app中使用富文本rich-text个人经验

rich-text是在uni-app一个内置组件&#xff0c;用于高性能地渲染富文本内容。先贴一下官方的属性列表&#xff1a; 先说一下“selectable” 长按选择区域复制&#xff0c;这个我在APP项目中 不起作用&#xff0c;可能像文档说的&#xff0c;只支持“百度小程序”吧。在APP端起作…...

Matlab|基于V图的配电网电动汽车充电站选址定容-可视化

1主要内容 基于粒子群算法的电动汽车充电站和光伏最优选址和定容 关键词&#xff1a;选址定容 电动汽车 充电站位置 仿真平台&#xff1a;MATLAB 主要内容&#xff1a;代码主要做的是一个电动汽车充电站和分布式光伏的选址定容问题&#xff0c;提出了能够计及地理因素和服…...

从零开始! Jupyter Notebook的安装教程

&#x1f680; 从零开始! Jupyter Notebook的安装教程 摘要 &#x1f4c4; Jupyter Notebook 是一个广受欢迎的开源工具&#xff0c;特别适合数据科学和机器学习的开发者使用。本文将详细介绍从零开始安装 Jupyter Notebook 的步骤&#xff0c;包括各种操作系统的安装方法&am…...

web前端信息卡:深入探索与实用指南

web前端信息卡&#xff1a;深入探索与实用指南 在数字化时代&#xff0c;web前端信息卡已成为我们日常生活和工作中的重要组成部分。这些小巧而强大的工具&#xff0c;能够在有限的空间内展示丰富的信息&#xff0c;提升用户体验。然而&#xff0c;设计一个出色的web前端信息卡…...

之所以选择天津工业大学,因为它是双一流、报考难度适宜,性价比高!天津工业大学计算机考研考情分析!

天津工业大学&#xff08;Tiangong University&#xff09;&#xff0c;简称“天工大”&#xff0c;位于天津市&#xff0c;是教育部与天津市共建高校、国家国防科技工业局和天津市共建的天津市重点建设高校、国家“双一流”建设高校、天津市高水平特色大学建设高校、中国研究生…...

WPF三方UI库全局应用MessageBox样式(.NET6版本)

一、问题场景 使用HandyControl简写HC 作为基础UI组件库时&#xff0c;希望系统中所有的MessageBox 样式都使用HC的MessageBox&#xff0c;常规操作如下&#xff1a; 在对应的xxxx.cs 顶部使用using 指定特定类的命名空间。 using MessageBox HandyControl.Controls.Message…...

ABAP-03基础数据类型

基本数据类型 数据类型默认大小&#xff08;byte&#xff09;有效大小初始值说明示例C11-65535SPACE文本字符&#xff08;串&#xff09;‘Name’N11-65535‘00…0’数字文本‘0123’T66‘000000’时间(HHMMSS)‘123010’D88‘00000000’日期(yyyymmdd)‘20090901’I4-231~232…...

Zabbix监控神通数据库教程

作者&#xff1a;乐维社区&#xff08;forum.lwops.cn&#xff09; 乐乐 神通数据库&#xff0c;即神舟通用数据库&#xff08;ShenTong Database&#xff09;&#xff0c;是我国自主研发的一款关系型数据库管理系统。它在国内市场有一定的应用&#xff0c;尤其是在一些对数据安…...

5.音视频基础 FLV

目录 简说FLV FLV Header FLV Body Tag Header ​编辑Tag Data Audio Data Video Data Script Data 简说FLV FLV格式可以包含音频、视频和文本数据&#xff0c;并且可以在网络上进行流媒体传输。优点是文件大小较小&#xff0c;压缩效率高&#xff0c;并且可以在较低…...

Ubuntu server 24 (Linux) 安装客户端(windows/linux) Zabbix 7.0 LTS Zabbix agent2

一 Ubuntu(linux)安装客户端 1 Ubuntu 24 安装Zabbix agent2 #安装agent库 sudo wget https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_7.0-1ubuntu24.04_all.deb sudo dpkg -i zabbix-release_7.0-1ubuntu24.04_all.deb sudo apt u…...

在 Ubuntu 上取消登录密码和锁屏功能的简易指南

你可以使用终端命令来直接设置取消登录密码和锁屏功能。以下是具体步骤&#xff1a; 取消登录密码 打开终端。编辑 /etc/gdm3/custom.conf 文件&#xff1a;sudo nano /etc/gdm3/custom.conf在 [daemon] 部分下&#xff0c;添加或修改以下行&#xff1a;AutomaticLoginEnable…...

PAT B1046. 划拳

题目描述 划拳是中国酒文化中一个有趣的组成部分。酒桌上两人划拳的方法为:每人口中喊出一个数字&#xff0c;同时用手比划出一个数字。如果谁比划出的数字正好等于两人喊出的数字之和&#xff0c;谁就赢了,输家罚一杯酒。两人同赢或两人同输则继续下一轮,直到唯一的赢家出现。…...

奥特曼谈AI的机遇、挑战与人类自我反思:中国将拥有独特的大语言模型

奥特曼在对话中特别提到&#xff0c;中国将在这个领域扮演重要角色&#xff0c;孕育出具有本土特色的大语言模型。这一预见不仅彰显了中国在全球人工智能领域中日益增长的影响力&#xff0c;也预示着未来技术发展的多元化趋势。 ①奥特曼认为AI在提升生产力方面已显现积极作用&…...

Java版-剑指offer数据结构与算法 视频教程 下载

Java版-剑指offer数据结构与算法 视频教程 下载 01-数据结构与算法入门基础 clip.mp4 02-clip1.mp4 03-clip2.mp4 04-基础数据结构&#xff1a;数组&链表&#xff08;一&#xff09;.mp4 05基础数据结构&#xff1a;数组&链表&#xff08;二&#xff09;.mp4 06-基…...

mac禁用电池睡眠-mac盒盖连接显示器

mac禁用电池睡眠-mac盒盖连接显示器-mac断点盒盖连接显示器 讲解&#xff1a;mac盒盖的时候连接显示器会睡眠并断开和显示器的连接&#xff0c;只有在电池->选项->选择使用电源适配器的时候防止睡眠&#xff0c;才可以连接电源线外界显示器 但是苹果的电池相当于手机电…...

最好用的智能猫砂盆存在吗?自用分享智能猫砂盆测评!

在现代都市的忙碌生活中&#xff0c;作为一名上班族&#xff0c;经常因为需要加班或频繁出差而忙碌得不可开交。急匆匆地出门&#xff0c;却忘了给猫咪及时铲屎。但是大家要知道&#xff0c;不及时清理猫砂盆会让猫咪感到不适&#xff0c;还会引发各种健康问题&#xff0c;如泌…...

LeetCode 每日一题 2748. 美丽下标对的数目

Hey编程小伙伴们&#x1f44b;&#xff0c;今天我要带大家一起解锁力扣上的一道有趣题目—— 美丽下标对的数目 - 力扣 (LeetCode)。这不仅是一次编程挑战&#xff0c;更是一次深入理解欧几里得算法判断互质的绝佳机会&#xff01;&#x1f389; 问题简介 题目要求我们给定一…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...

一些实用的chrome扩展0x01

简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序&#xff0c;无论是测试应用程序、搜寻漏洞还是收集情报&#xff0c;它们都能提升工作流程。 FoxyProxy 代理管理工具&#xff0c;此扩展简化了使用代理&#xff08;如 Burp…...

Linux安全加固:从攻防视角构建系统免疫

Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...