C语言之“动态内存管理”

这一节的内容是动态内存管理喔,指针+结构体+动态内存管理,是学习数据结构非常重要的知识,大家加油!!

点赞加关注,追番不迷路。

在这里插入图片描述

1. 为什么要有动态内存分配

我们之前学习的内存开辟方式是:

int a = 10;
int arr[10] = 10;

但是这种方法有弊端:
1.空间开辟的大小是固定的
2.数组在申明的时候就必须指定它的长度,而且一旦确定不能修改

但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道,那数组的编译时开辟空间的方式就不能满足了。

C语言引入了动态内存开辟,让程序员自己可以申请和释放空间,比较灵活,且节约空间or不浪费空间

2. malloc和free(动态内存的申请,释放)

malloc是memory allocate:内存分配

free是自由的意思,即释放内存

malloc和free最好成对使用,有申请有释放。

2.1 malloc

malloc的基础认识

  1. malloc是一个申请动态内存开辟的函数。

(1)malloc的功能是allocate memory block:开辟内存块
(2)malloc的头文件是stdlib.h
(3)malloc所生成的空间是连续的

2.函数的形式是void* malloc (size_t size)这个函数向内存申请以块 连续 可用的空间,并返回指向这块空间的指针。

  • 当需要多大的字节时,将这个数字传过去(参数是size[空间大小],参数的单位是字节)
  • 这个函数返回的是void*指针,意思是当开辟了size大小的空间时,会将这个空间的起始地址传回来。如果申请失败,会返回空指针。
  1. malloc申请的空间和数组的空间有什么区别?

1.malloc申请的是动态内存空间,它的大小可以调节
2.开辟空间的位置不一样
在这里插入图片描述

malloc的应用

假设想申请10个整型的空间,如何申请?

  • 1.首先:将10个整型的大小作为参数传给函数mallocmalloc(10*sizeof(int))
  • 2.接下来:接收申请的空间的地址,用什么类型来接收呢?返回值的类型是 void*,用void*接收的话,之后不好使用,我们可以将地址强制类型转化成相应的,即具体在使用的时候使用者自己来决定。
int* p = (int*)malloc(10 * sizeof(int));
  • 3.最后进行判断,看是否开辟成功;如果失败的话,返回原因。如果成功的话,则返回一个指向开辟好空间的指针,最后再在这10个整型的空间(40字节)存上数据。
#include<stdio.h>
#include<stdlib.h>
int main()
{
   
	int* p = (int*)malloc(10 * sizeof(int));
	//接下来这一步很重要,一定要检查是否为空指针,如果是,提前返回
	if (p == NULL)
	{
   
		perror("malloc");
		return 1;  
		//在知道原因之后就退出吧,return 0是正常返回,非0是不正常返回
	}
	else
	{
   
		int i = 0;
		for (i = 0; i < 10; i++)
			*(p + i) = i;
			//或者p[i]=i;
	}
	return 0;
}

2.2 free

1.函数free用来释放动态开辟的内存。 空间被释放之后,ptr指向的空间不属于当前程序,但是还是可以找到的(野指针)

2.函数free的原型是:void free (void* ptr)

  • 将动态内存的起始地址传过去
  • 没有返回值(void)

举例:在前面我们申请了40个字节的空间,地址是p,现在想要释放:

free(p);在这之后,再写一个p=NULL;,防止p称为野指针

3.free的头文件是stdlib.h

  • 如果参数 ptr 指向的空间不是动态开辟的(比如 int a = 0; int* ptr = a;),那free函数的行为是未定义的。
  • 如果参数 ptr 是NULL指针,则函数什么事都不做。

3. calloc和realloc

3.1 calloc

1.calloc 函数也用来动态内存分配。原型如下:

void* calloc (size_t num, size_t size);

它的含义是:开辟num个大小为size的空间,并且把空间的每个字节初始化为0。

2.calloc和malloc的区别是:

(1.calloc会将每个字节初始化为0.
(2.malloc是写总的空间大小,calloc是分开。

int main()
{
   
	// 比如都申请10个整型的空间
	int* ptr1 = (int*)malloc(10 * sizeof(int));
	int* ptr2 = (int*)calloc(10, sizeof(int));
}

3.2 realloc

1.re再次,alloc开辟内存。realloc是调整

2.函数原型: void* realloc (void* ptr, size_t size);
• ptr 是要调整的内存地址
• size 调整之后新大小
• 返回值为调整之后的内存起始位置。
• 这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。

3.realloc在调整内存空间的是存在两种情况:
◦ 情况1:原有空间后面有足够大的空间(直接在原有内存之后追加空间)
◦ 情况2:原有空间后面没有足够大的空间(realloc函数会直接在内存的堆区寻找一块新的满足大小的空间;再将旧的数据拷贝到新的空间;最后释放旧的空间)

在这里插入图片描述

4.返回的值有可能是新地址,旧地址,空指针,我们不清楚什么情况。如果realloc用原来动态内存的空间来接收,如果后续空间不够,原来的数据都有可能搞丢。为了防止数据丢失,我们可以将返回值放在新的指针中。

#include<stdio.h>
#include<stdlib.h>
int main()
{
   
	int* p = (int*)icalloc(10, sizeof(int)); //这里地址是p
	if (p == NULL)
	{
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值