动态内存管理(扫盲式讲解)

前言:学好数据结构的三大法宝:指针、结构体、动态内存管理,指针前面讲的已经很细了,大家看完了基本上指针方法是没啥问题的

1 为什么要有动态内存的开辟?

因为动态内存的开辟是在堆区里面的,可以释放,但是栈区的内存空间开辟是死的,无法释放。

2 怎么合理使用动态内存呢?

首先你要学会开辟内存,然后在合适的条件下释放内存

3 动态内存的应用

(1)首先带大家了解动态内存的函数

one:malloc

下面我们来在堆区放一个数组

malloc开辟空间有两种情况

1 开辟失败,返回的就是空指针

2 开辟成功返回一个指向好的空间的地址

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{
	int arr[10] = { 0 };
	int* p = &arr;
	p =(int*)malloc(sizeof(arr)*sizeof(int));
	//这里要判断一下,空间开辟是否失败,如果失败malloc返回的就是空指针
	if (p == NULL)
		return 1;
	for (int i = 0; i < 10; i++)
	{
		p[i] = i;
		printf("%d ", p[i]);
	}
	//这里malloc开辟的空间用完了记得释放
	free(p);
	//然后把指针p置空
	p = NULL;
	return 0;
}

给大家看看调试效果:

变成空指针了

two:calloc

calloc与malloc只有一个区别,返回地址之前会把指针指向的内容全部初始化为0

int main()
{
	int* p = (int*)calloc(10,sizeof(int));
	//好习惯是每天养成的,记住一定要判断是否是空指针
	if (p == NULL)
		return 1;
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", p[i]);
	}
	free(p);
	p = NULL;
	return 0;
}

three:realloc

realloc的优点是让动态内存的空间管理非常灵活,如果觉得申请的内存空间大了,可以扩容,小了可以缩减。

扩容分为两种情况

(1)原有的空间后面的空间足够大,那么返回的就是原来的地址

(2)原有的空间后面的空间不够了,那么就要重新开辟一块空间,把原来地址里面的内容取出来放在现在开辟好的新的空间,返回的也是新的地址的起始地址

int main()
{
	int* p = (int*)calloc(10,sizeof(int));
	//好习惯是每天养成的,记住一定要判断是否是空指针
	if (p == NULL)
		return 1;
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", p[i]);
	}
	//现在我认为我的空间开辟小了想要扩容
	p = (int*)realloc(p, sizeof(int) * 15);//后面的sizeof(int) * 15是新空间的大小,单位是字节
	//然后我继续打印
	for (int i = 10; i < 15; i++)
	{
		p[i] = i;
		printf("%d ", p[i]);
	}
	free(p);
	p = NULL;
	return 0;
}

最后再提一下如果realloc前面的指针是空指针,那么realloc的功能就等同于malloc了

猜你喜欢

转载自blog.csdn.net/2301_79811170/article/details/134843085