一、本课重点
- 为什么存在动态内存管理
- 动态内存函数介绍
- malloc
- free
- calloc
- realloc
- 常见动态内存错误
- 几个经典的面试题
- 柔性数组
二、为什么存在动态内存管理
在堆区(heap)进行分配,可以节省空间
三、动态内存函数介绍
1.malloc
向内存申请一块连续可用的空间,并返回指向这块空间的指针。
- 如果开辟成功,则返回指向开辟好空间的指针;如果开辟失败,则返回一个NULL的指针,因此malloc的返回值一定要检查。
- 返回值类型是void*,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。
- 如果参数size为0,malloc的行为是标准未定义的,取决于编译器。
2.free
将申请的空间释放,p指向的空间虽然被释放,但是依然可通过p找到这块空间,需要将p手动赋值,断开与p之间的联系,以免造成问题。
3.calloc
与malloc区别在于在返回地址之前会把申请的空间的每个字节初始化为全0
4.realloc
调整动态开辟内存空间的大小
realloc使用的注意事项
1.如果p指向的空间之后有足够的空间可以追加,后返回p
2.如果p指向的空间之后没有足够的内存空间可以追加,则realloc函数会重新找一个新的内存空间区域
开辟一块满足需求的空间,并且把原来的内存中的数据拷贝回来,释放旧的内存空间
最后返回新开辟的内存空间地址
得用一个新的变量来接收realloc函数的返回值
四、常见动态内存错误
- 对NULL进行解引用操作
- 对动态开辟的内存越界访问
- 对非动态开辟空间的free释放
- 使用free释放动态开辟内存的一部分(注意指针的位置)
- 对同一块动态内存多次释放
- 对动态开辟空间忘记释放,会造成内存泄漏
五、几个经典的面试题
1.动态内存泄露
2.返回栈空间地址问题
栈区会自动销毁,引起非法访问
堆空间需要释放才会销毁
六、(flexible arry)柔性数组
C99中,结构体中的最后一个成员可以是未知大小(前面至少存在一个结构体成员),它的空间开辟需要使用malloc
结构体中柔性数组成员不占大小(sizeof返回的这种结构大小不包括柔性数组的内存)
定义arr数组大小为5个整型
使用指针创建可调整大小的空间(malloc函数)- 代替柔性数组
两种方法对比:(malloc函数开辟空间时,会找足够的空间去开辟,会造成内存碎片)
- 柔性数组优势:
- 1.使用malloc函数少,不用多次释放空间,减少失误可能性(方便内存释放)
- 2.减少内存碎片,内存利用率高
- 3.开辟的空间连续,访问空间时速度更快、效率更高