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