【C语言进阶学习笔记】五、动态内存分配(爆肝吐血力作,强烈建议收藏!!!)

前言现代计算机基本都是基于冯诺伊曼结构体系设计出来的,冯诺伊曼结构体系的核心就是“存储程序”,将程序(指令集)和数据以同等地位存储在内存中。但是我们的内存空间并不是无限大的,所以为了高效的利用好内存空间,操作系统会对这些内存空间进行相应的分区,不同区域的内存有其对应的功能和使用方式。比如局部变量、函数形参通常是存储在栈区的,这部分内存空间的特点就是临时使用,用完即释放(当然这个都是由操作系统自动完成的,不需要程序员的干预);再比如全局变量通常存放在静态区,此外由static修饰的局部变量也会放到静态
摘要由CSDN通过智能技术生成

前言

现代计算机基本都是基于冯诺伊曼结构体系设计出来的,冯诺伊曼结构体系的核心就是“存储程序”,将程序(指令集)和数据以同等地位存储在内存中。但是我们的内存空间并不是无限大的,所以为了高效的利用好内存空间,操作系统会对这些内存空间进行相应的分区,不同区域的内存有其对应的功能和使用方式。
在这里插入图片描述
比如局部变量、函数形参通常是存储在栈区的,这部分内存空间的特点就是临时使用,用完即释放(当然这个都是由操作系统自动完成的,不需要程序员的干预);
再比如全局变量通常存放在静态区,此外由static修饰的局部变量也会放到静态区(所以static修饰局部变量,本质上是改变了其存储的位置,从栈区-- > 静态区),这部分内存空间就是生命周期很长,长到整个程序运行结束;
再例如我们使用的常量字符串,会被保存到常量区,这部分内存区域的特点就是类似于“常量”,不可被修改,相当于添加了一个“const”的buff。
(我的废话:在学习的时候如果可以多多思考,联系不同的知识点,当将这些内容串起来时,可以形成一个比较宏观、整体的角度。更进一步,如果我们能够从中找到乐趣就更好了!现在我们进入正题吧!)


全文结构:
在这里插入图片描述


一、寻根问底

什么是动态内存分配 / 管理?

由程序员根据实际编程需要向操作系统申请,在堆区上开辟的,供程序员操作使用和维护的内存空间,程序员的游乐园!通常是一些临时用到的数据或者变量,随时开辟,用完随时释放,而不必等到函数结束后由操作系统回收!

为什么需要动态内存分配?

实际编程中,不仅需要大小固定的内存空间,往往还需要大小可变的内存空间。
比如说如果我们要建立一个通讯录,用来存放相关信息(姓名、性别、年龄、电话等),这种复杂的数据,我们知道要用结构体类型来存储,而且要用结构体数组来存,但是问题是“这个数组的大小应该多大呢?”
这个问题确实不好回答,如果长度给小了,那么就会导致数据溢出,进而引发程序崩溃。
如果给大了,又会导致存储空间大量浪费,空间利用率低。
为了解决这一类问题,就出现了动态内存分配,内存空间按需索取,要多少给多少!

怎么建立动态内存分配?

通过系统提供的4个库函数实现,malloc\calloc\realloc\free,这四个函数后面我们会详细介绍。


二、动态内存函数

注意:以下说的四个函数的头文件均为:stdlib.h

malloc

函数原型:void * malloc(size_t size);

size_t就是unsigned int(无符号整型)

这个函数的作用就是在动态存储区中分配一个长度为size个字节的连续空间,并返回指向该空间的指针。

1)如果开辟成功,则返回一个指向开辟好空间的指针。
2)如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。
3)返回值的类型是void * ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。
4)如果参数size为0,malloc的行为是标准是未定义的,取决于编译器。

动态开辟的空间如何释放和回收呢?
C语言提供了一个专门完成这个功能的库函数-- - free


free

函数原型:void free(void* p)

free的作用就是释放指针变量p所指向的动态空间,使这部分空间能够重新被利用。

1)如果参数ptr指向的空间不是动态开辟的,那free函数的行为是未定义的。
2)如果参数 ptr是NULL指针,则函数什么事都不做。


现在来看一下实际的使用:

#include<stdio.h>
#include<stdlib.h>
int main()
{
   
	//1.通过动态开辟申请10个int类型的空间
	int* ptr = (int*)malloc(10 * sizeof(int));//通常结合sizeof一起使用
	//根据实际使用强制类型转换为想要的类型
	//2.malloc有可能申请空间失败,所以需要判断一下
	if (ptr == NULL)
	{
   
		perror("main");//perror是一个报错函数,实际出错时打印效果为:main:xxxxxx(错误原因)
		return 0;//出错就直接结束函数
	}
	//3.使用 给这10个整型空间赋值
	for (int i = 0; i < 10; i++)
	{
   
		*(ptr + i) = i;
	}
	//打印一下
	for (int i = 0; i < 10; i++)
	{
   
		printf("%d ", ptr[i]);//这里可以直接使用
  • 18
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大家好我叫张同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值