每天进步一点点,希望的火苗不熄灭。
目录
一、动态内存分配存在的原因
在之前我们学习过数组的内存开辟方式
//在内存中开辟一块能容纳10个int型数据的空间,并将它进行不完全初始化
int arr[10]={0};
图解如下:不完全初始化只将数组第一个元素a[0]初始化为0,a[1]~a[9]为默认值。假设我们在整个程序运行过程中只使用到a[0]的话,那么就会造成空间的浪费。
而另外一种情况,假设我们开辟的空间比我们将要使用的少的话,那又会造成空间的不足。
为了更好的利用内存空间我们引入了动态内存分配。
二、动态内存开辟的方式
1. malloc和free
malloc:C语言提供的一个动态内存开辟的函数,我们使用此函数来完成动态的内存开辟。
使用格式:void* malloc (size_t size);
int* pa = (int *)malloc(40);
此句代码的意思:在内存中开辟一块大小为40字节的内存空间,并将此空间的首地址返回给pa;
因为原来malloc函数返回类型为(void*)任意型,我们便可以将他强制转换为我们需要的指针类型。
![](https://i-blog.csdnimg.cn/blog_migrate/7e4da4f7baaae8b2b068051f85fc6b7d.jpeg)
总结:
4.返回值的类型是void*,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。
5.如果参数size为0,malloc的行为是标准是未定义的,取决于编译器。
free:C语言提供的专门用来做动态内存的释放和回收的;
使用格式:void free (void* ptr);
使用示例:
free(pa);
pa=NULL;
此句代码的意思:将pa指针指向的那块内存空间还给操作系统,然后将pa指针置为空;
注意:pa必须是动态开辟的内存空间的起始地址;
最后将pa指针置为空的原因是:虽然将内存空间还给操作系统,但pa还是指向那块内存空间,但又无法访问那块内存空间,pa变成了所谓的野指针,因此要将pa=NULL;
我们通常将malloc和free结合起来,使用malloc开辟内存空间,利用free来完成空间的释放,两个搭配起来使用。
我们如果只开辟内存空间而不进行释放的话:
一方面:在程序运行结束后操作系统会帮助我们进行内存空间的回收;
另一方面:如果程序一直在运行申请的空间不会得到回收,而又不断地申请空间,那就会造成内存泄漏问题(可以使用的内存容量不断地在减少)造成电脑死机等问题。
2. calloc
calooc:与malloc功能类似也用来动态内存分配;
使用格式:void* calloc (size_t num, size_t size);
函数功能:为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0。
与malloc的区别:calloc会在返回地址之前把申请的空间的每个字节初始化为全0。
使用示例:
int* p=calloc(10, sizeof(int));
此句代码的意思:在内存中开辟一块大小为10*sizeof(int)的内存空间,并将此空间的首地址返回给p,并将这些内存空间全部初始化为0;
总结:
1. 我们对申请的内存空间的内容要求初始化,那么可以很方便的使用calloc函数来完成任务。
2.calloc开辟的内存空间也要通过free释放;
3. realloc
realloc函数的出现让动态内存管理更加灵活。有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了合理的时候内存,我们一定会对内存的大小做灵活的调整。那realloc函数就可以做到对动态开辟内存大小的调整。
使用格式: void* realloc ( void* ptr , size_t size );ptr:是要调整的内存地址;size:调整之后新大小;返回值:调整之后的内存起始位置。
![](https://i-blog.csdnimg.cn/blog_migrate/34caaca1b6f5e22de599311f46788802.jpeg)
三、C程序的内存开辟
下面简单介绍一下C程序在内存中的存放情况。
内存中有三区(堆区、栈区、静态区),各区存放情况如下:
堆区:malloc、calloc、realloc、free动态内存分配
栈区:局部变量、形参;
静态区:全局变量、静态变量。