一动不动是王八?动态内存有话说

news2024/11/16 13:44:32

文章目录

  • 前言
  • 动态内存函数介绍
    • malloc
    • free
    • calloc
    • realloc
  • 柔性数组
    • 柔性数组特点
    • 柔性数组的优点
      • 方便内存释放
      • 提高我们的访问速度
  • 总结

前言

一动不动是王八,出自2014年的春晚,小时候经常喜欢说这句话,那在我们C语言中,我们知道,通常我们开辟一块空间用于存放变量的时候,这块空间是不会改变大小的,但是有的时候,需要我们程序运行起来才会知道我们需要多大的内存空间,那这种情况下,我们只能创建一个很大的数组,用来存放,这个时候就出现了不必要的浪费,那这个时候,就出现了我们的动态内存,让我们的内存不在做“王八”。

动态内存函数介绍

malloc

在这里插入图片描述

malloc,一个用于开辟连续内存空间的函数,它可以像内存申请一块空间,然后返回这块空间起始地址的指针,对于我们的malloc来说,如果这块空间申请失败的话,会返回我们的空指针NULL,那同时我们看到malloc的返回类型是void*,因为我们的malloc是不知道我们申请的空间是给什么类型去使用的,所以我们一般会对申请下来的空间进行强转,我们给malloc传过去的size代表着我们需要申请多少个字节的空间,在C语言标准中,是没有明确规定我们的size等于0会发生什么,所以当size等于0的时候,会发生什么取决于编译器,如果我们想用malloc申请一块20个字节的空间给我们char类型的数组str用,那怎么用呢?

int main()
{
	char* str=NULL;
	str=(char*)malloc(20);
	if(str==NULL)
	{
		perror(str);
	}
	return 0;
}

那这样就开辟了一块20个字节的空间给我们的str使用。

free

在这里插入图片描述
free,当我们用动态内存函数开辟空间之后,是需要进行内存释放的,不然就会造成内存泄漏,或者其他问题,这个时候,内存释放用的就是我们的free,它可以对我们开辟的空间进行释放,当我们进行释放之后,我们最好让先前接收这片空间的指针置空,以免造成野指针问题,那有了free之后,我们对于上面的例子代码进行升级。

int main()
{
	char* str=0;
	str=(char*)malloc(20);
	if(str==NULL)
	{
		perror(str);
	}
	free(str);
	str=NULL;
	return 0;
}

calloc

在这里插入图片描述

calloc,和我们的malloc用处是一样的,但是传参是不一样的,对于我们的malloc来说,可以申请任意字节的空间,比如17、21,那这些字节也可以强转给我们的int类型,只不过我们在往申请的这片空间中放东西的时候,因为我们的int类型是4个字节,所以放入到最后字节不够4个字节的空间时,就会产生截断,放不完全,而我们的calloc传的两个参数,第一个是要申请多少个元素,第二个是每个元素的大小,比如我们要为一个10个元素的int类型的数组申请空间,就可以像下面这样来申请。

int main()
{
	int* num=0;
	num=(int*)calloc(10sizeof(int));
	if(num==NULL)
	{
		perror(num);
	}
	free(num);
	num=NULL;
	return 0;
}

其中我们的calloc和malloc还有一个最大的差别,对于我们的malloc来说,它申请下来的空间是不会对其初始化的,所以malloc内存空间里面放的值是不知道的,但是我们的calloc是会对申请的空间进行初始化的,会全部初始化成0。

realloc

在这里插入图片描述

realloc,是让我们内存“动”起来的关键所在,它的作用是我们发现我们用malloc或者calloc申请的空间不够使用的时候,用来“扩容”的,它的参数有两个,第一个就是我们指向我们申请下来那块空间起始地址的指针,第二个就是“扩容”多少个字节,同样,返回的是申请到空间的起始地址,但是如果我们原空间后面的空间不够“扩容”的字节,就会重新找一片空间,然后把原空间的数据拷贝过去,同样,如果申请失败会返回空指针,所以对于我们要“扩容”的时候,最好是在创建一个指针变量,先用新创建的指针变量接收realloc的返回值,然后判断,申请成功就把realloc申请下来的空间赋值给我们的原指针。

int main()
{
	char* str=NULL;
	str=(char*)malloc(20);
	if(str==NULL)
	{
		perror(str);
	}
	char* p=NULL;
	p=(char*)realloc(str,10);
	if(p!=NULL)
	{
		str=p;
		p=NULL;
	}
	free(str);
	str=NULL;
	return 0;
}

柔性数组

柔性数组,于C99标准中定义,它处于结构体当中,当我们结构体的最后一个成员是一个未知大小的数组的时候,就是我们的柔性数组,当然,这个结构体一定要有其他的成员,可能看字看不懂?那我们直接上代码。

struct st_type
{
 	int i;
 	int a[0];//柔性数组
};

这种写法可能在有的编译器上跑不过,那我们就换一种写法。

struct st_type
{
 	int i;
 	int a[];//柔性数组
};

柔性数组特点

我们前面提到,柔性数组之前必须至少有一个成员,那是为什么呢?对于柔性数组,如果用sizeof计算它的大小会是多少呢?我们用编译器试一下。
在这里插入图片描述
我们可以看到,整个结构体大小是4,那为什么是4?一个int就占用了四个内存了,何况我们还有一个数组,这里就直观的说明了,对于我们的柔性数组成员,它是不计入结构体大小的,如果这个结构体就它一个成员,那它大小就是0,那不方便我们进行后面的操作。同样对于我们柔性数组来说,它的内存占用也是用我们的malloc来申请,它申请的时候不和我们上面申请的时候是一样的,它需要先将我们结构体内其他成员的空间先跨过,才是自己的。

type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));

柔性数组的优点

方便内存释放

当里面的成员不是柔性数组而是指针的时候,在使用的过程中,我们对其内部进行了二次的内存分配,而且把整个结构体的指针返回去了,别人使用这个结构体指针,他并不知道里面进行了二次的内存分配,他直接用free释放了整个结构体,不知道要对内部进行free,但是要是柔性数组,就没有这个问题,free一次就行了。

提高我们的访问速度

因为我们申请下来的空间是一片连续的空间,是更加有利于访问的。

总结

动态内存大大的提高了对内存空间的利用,避免了一些不必要的内存浪费。

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

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

相关文章

年度征文|一个业余电脑玩家的30年(1992-2022)

《论语为政》:“五十而知天命”。岁月真的是一把刀,一晃已过不惑之年,还有几天就要进入知非之年。不论知非还是知天命,反正是花甲将至而从心所欲了。年少时因某种不合机缘,错与IT界擦肩而过,每每想起就扼腕…

gradel学习+IDEA配置

Gradle的下载 Gradle下载地址如下 https://gradle.org/releases/ 我自己的下载的7.4.2 可以选择下载完整的压缩包,将压缩包解压到自己指定的目录中即可。 Gradle安装 1、配置系统变量 GRADLE_HOME 2、配置环境变量 %GRADLE_HOME%是获取变量名称为GRADLE_HOME的…

项目看板开发经验分享(一)——光伏绿色能源看板

今天新开一个系列,专门介绍近期工作中开发的几个比较酷炫的看板的开发思路与经验分享。第一节我们就来介绍下这个光伏绿色能源看板,整体浏览如下: 那就直接进入正题吧—— 0、可复用组件panel 在讲解各个模块之前,我们先来完成一…

Mybatis 框架下 SQL 注入攻击的 3 种方式

SQL注入漏洞作为WEB安全的最常见的漏洞之一,在java中随着预编译与各种ORM框架的使用,注入问题也越来越少。 新手代码审计者往往对Java Web应用的多个框架组合而心生畏惧,不知如何下手,希望通过Mybatis框架使用不当导致的SQL注入问…

Node.js学习笔记

Node.js学习笔记 浏览器的内核包括两部分核心:DOM渲染引擎、JavaScript解析引擎。脱离浏览器环境也可以运行JavaScript,只要有JavaScript引擎就可以。 Node.js是一个基于Chrome V8引擎的JavaScript运行环境。Node.js内置了Chrome的V8 引擎,…

SpringBoot项目部署

系列文章目录 Spring Boot[概述、功能、快速入门]_心态还需努力呀的博客-CSDN博客 Spring Boot读取配置文件内容的三种方式_心态还需努力呀的博客-CSDN博客 Spring Boot整合Junit_心态还需努力呀的博客-CSDN博客 Spring Boot自动配置--如何切换内置Web服务器_心态还需努力呀…

Open3D SOR滤波(Python版本)

文章目录一、简介二、实现代码三、实现效果参考资料一、简介 SOR滤波过程相对简单,其原理是通过查询点与邻域点集之间的距离统计判断来进行过滤离群点。假设一个点的邻近点集符合正太分布,因此我们可以通过计算出该点到它所有临近点的平均距离meanD和标准…

国内怎么体验openAI chatGPT

怎么体验openAI chatGPT 一,前提 1,先准备好一个gmai的邮箱,注册时要用 2,(懂得都懂) 3,ChatGPT:网址 二,开始注册 1,sign up,用Gmail注册,我…

洛谷P8942 Digital Fortress

题目大意 给定一个区间,构造一个单调不减的序列,使得其前缀异或和与后缀异或和均单调递减,判断这种序列是否存在并输出任意一种解。 思路 暴力 dfs 当然会 TLE,所以我们要仔细分析: ① 在什么情况下异或和能够单调不减&#x…

2023/1/15 JS-原型与原型链

1 什么是原型 原型是Javascript中的继承的基础,JavaScript的继承就是基于原型的继承。每一个JS对象都可以获得自己的原型,通过原型可以共享函数对象和实例对象之间的属性和方法。 原型的出现,就是为了解决 构造函数 的缺点: 每一…

HTB-Shoppy

HTB-Shoppy信息收集开机提权信息收集 22和80。 能扫描出来的东西很杂,但是admin和login可以重点关注。 访问其中之一,能发现是一个登陆界面。 对其进行简单的sql注入测试。输入admin’or11#会出现504超时,判断可能是因为有sql防御措施所致。…

SpringCloud Netflix复习之Zuul

文章目录写作背景Zuul是什么Zuul的核心功能上手实战SpringCloud中Zuul如何使用自定义过滤器配置全局Fallback降级Zuul请求头Ribbon等其他参数配置过滤敏感请求头参数配置开启Ribbon懒加载和Ribbon超时配置开启Hystrix超时配置(一般不配置没啥用)源码部分请求入口ZuulServlet注入…

C++入门--list

目录 list的介绍: list的构造: 遍历: reverse、sort、unique list的模拟实现: 反向迭代器: list与vector的比较: list的介绍: list是序列容器,允许在序列内的任何位置执行O(…

RocketMQ源码(19)—Broker处理DefaultMQPushConsumer发起的拉取消息请求源码【一万字】

基于RocketMQ release-4.9.3,深入的介绍了Broker处理DefaultMQPushConsumer发起的拉取消息请求源码。 此前我们学习了RocketMQ源码(18)—DefaultMQPushConsumer消费者发起拉取消息请求源码。我们知道consumer在发送了拉取消息请求的时候,请求的Code为PUL…

【 JavaScript编程详解 -1 】什么是JavaScript ?

文章目录简介Java与JavaScript的不同Javascrpt可以做什么JavaScript的构成为什么可以在浏览器中运行如何将 JavaScript 代码添加到网站&#xff1f;方法1- \<script\>标签内嵌JavaScript方法1- \<script\>标签引入外部JavaScript文件方法3- 内联 JavaScript编辑器推…

蛇形矩阵(简单明了的方法)

T112524 【数组2】蛇形矩阵 题目来源 AC代码 #include<stdio.h>int main() {int arr[111][111];int n 0;scanf("%d",&n);int temp 0;int sum 1;while(temp<(2*n-2)){for(int i0;i<n;i){for(int j0;j<n;j){if((ij) temp){if(temp%2 0){arr[…

基于FPGA的时间数字转换(TDC)设计(三)

1.多相位TDC计时测试 以下为多相位TDC计时的测试。图1为多相位TDC计时的测试框图,利用信号发生器,产生两路同相位、具有固定延时的脉冲信号,一路作为Start信号,另外一路作为Stop信号。由于分辨率为312.5ps,因此以312.5ps为步进,对Stop信号进行延时,扫描一个周期,通过UA…

红米 12C earth Fastboot 线刷包 root TWRP 刷入magisk recovery卡刷

红米 12C earth Fastboot 线刷包 root TWRP 刷入magisk recovery卡刷 红米 12C (earth) 国行版 Fastboot 线刷包 & Recovery 卡刷包 ROM 红米 12C earth Fastboot 线刷包 root TWRP 刷入magisk recovery卡刷下载 红米 12C 稳定版 Fastboot 线刷包 要安装国行版 红米 12C F…

对笔试使用《剑指offer》吧(第十天)

跟着博主一起刷题 这里使用的是题库&#xff1a; https://leetcode.cn/problem-list/xb9nqhhg/?page1 目录剑指 Offer 62. 圆圈中最后剩下的数字剑指 Offer 64. 求12…n剑指 Offer 65. 不用加减乘除做加法剑指 Offer 62. 圆圈中最后剩下的数字 剑指 Offer 62. 圆圈中最后剩下的…

【BP靶场portswigger-客户端12】跨站点请求伪造CSRF-12个实验(全)

前言&#xff1a; 介绍&#xff1a; 博主&#xff1a;网络安全领域狂热爱好者&#xff08;承诺在CSDN永久无偿分享文章&#xff09;。 殊荣&#xff1a;CSDN网络安全领域优质创作者&#xff0c;2022年双十一业务安全保卫战-某厂第一名&#xff0c;某厂特邀数字业务安全研究员&…