一.为什么要存在动态内存分配:
下图是不同类型数据在内存中的分配:
像上述代码中,i是机器在内存中的栈区开辟了4个字节,arr[20]是机器在内存中的栈区开辟了连续的20个字节存放。而这些大小已经被机器限制死了,无法去改变,这就很有局限性,而如果存在动态内存分配程序员⾃⼰可以申请和释放空间,就⽐较灵活了。
二.动态内存分配的相关函数:
这些动态内存分配的函数使用时必须包括头文件<stdlib.h>
1.malloc:
使用时必须包括头文件<stdlib.h>
当这个程序运行结束时,这申请的空间会返还给操作系统。
这时申请的内存空间太大,系统没有足够的空间。
2.free:
![](https://i-blog.csdnimg.cn/blog_migrate/6c71edcbf1434565fe3ad0755ace17b8.png)
3.calloc:
![](https://i-blog.csdnimg.cn/blog_migrate/4b491811c9fcd1793a7de361faeca72d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2fa58ff8b8666dd1da28db5160b13383.png)
![](https://i-blog.csdnimg.cn/blog_migrate/059ad9c9d3cade9aac664f707dbacf34.png)
4.realloc:
![](https://i-blog.csdnimg.cn/blog_migrate/c21dd7ea92e8acaeaadb929165458893.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b4e2acc88aec437a23ef0b25ca8bf947.png)
三.在开辟动态内存空间时容易犯的错误:
1.对NULL指针的解引用操作:
因为没有提前进行判断p是否为空指针,所以导致调试时出现了异常。
所以要对其做一个判断:
此时用assert函数对其进行断言或者用if语句判断:
2.对动态开辟空间的越界访问:
这跟数组非常相似。
3.对非动态开辟内存使用free释放:
当去调试的时候你会发现:
压根没有这块内存空间去释放:
运行的时候也会卡死
4.使⽤free释放⼀块动态开辟内存的⼀部分:
在前面的代码中我们利用循环去给开辟的内存空间去赋值:
这是一种循环的写法,还有一种:
虽然这两段代码都可以实现对其赋值但是,在代码二中p的指向不断移位,结束之后就不再是起始位置,而内存释放时要的是开辟的空间的起始位置。
5.对同⼀块动态内存多次释放:
但是如果你每次释放完内存时,都将指针置为空,此时也能正常运行。
6.动态开辟内存忘记释放(内存泄漏):
所以当申请完内存空间想到的第一步就是用完要释放申请的内存空间。
四.动态内存经典笔试题分析:
1.![](https://i-blog.csdnimg.cn/blog_migrate/3b9d8c906be3f3a66fd4568d62c069ac.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a6562b1e0cc2d0a6fbe6957fb64ff329.png)
![](https://i-blog.csdnimg.cn/blog_migrate/bbe22b9a83979cdb09d05455ff128acd.png)
![](https://i-blog.csdnimg.cn/blog_migrate/132f004bfcc3e0d16a39ecfef84c1337.png)
2.返回栈空间指针的问题:
不能返回临时变量的地址。
可能打印出来,也可能打印不出来。
图解:
3.
没有释放开放的内存空间,没有free,造成内存泄漏
4.
这个题目要我们记住的也是free完之后要将其置为空指针。
五.柔性数组:
C99 中,结构中的最后⼀个元素允许是未知大小的数组,这就叫做『柔性数组』成员。
根据这句话可以知道,要想使用柔性数组,则:
1.必须在结构体中而且要是最后一个结构体成员。
2.最后一个成员是数组,并且是没有指定这个数组的大小。
1.柔性数组的写法:
2.柔性数组的特点:
• 结构中的柔性数组成员前⾯必须⾄少⼀个其他成员。
• sizeof 返回的这种结构⼤⼩不包括柔性数组的内存。
![](https://i-blog.csdnimg.cn/blog_migrate/67c4595a14cb5afcf3f14b925e9444dc.png)
3.柔性数组的使用:
这里能使用malloc开辟空间所以也能使用realloc来开辟空间,因为前面的成员的内存空间是固定的,所以当用realloc去调整大小时,是后面数组的大小在不断变化,所以才称为柔性数组。这也就是为什么柔性数组要放在结构体成员最后。
调整柔性数组的空间大下:
法一:
法二:先开辟一个内存空间给结构体中的成员,再单独给结构体成员中的柔性数组再单独开一个内存空间: