1 为什么需要动态内存管理
提出动态内存管理的原因是,在某些情况下,静态内存管理存在bug(缺陷),什么缺陷呢? 试想一下当我们在定义一个数组的时候,必须指明该数组的大小, 由于我们提前无法知道程序运行前需要多大长度的空间,因此我们采取静态内窜管理的方式是盲目的. 如果提前设置的长度少了,当我们输入的数据量大于数组长度的时候, 就会出错。 所有一般我们提前给定的空间就比较大,这时,当我们输入的数据量很小的时候,就会造成内存资源的浪费。基于静态内存的诟病,我们的动态内存管理应运而生。动态内存管理主要是为了解决那些只有在程序运行时才知道所需内存的大小的情况,此时由程序员来动态开辟内存。
2 C语言中通过什么来实现对动态内存管理呢?
1 malloc 函数
2 calloc 函数
3 realloc 函数
4 free 函数
3 男一号 malloc 函数登场----开房的
函数功能: 开辟size 个字节大小的内存空间
函数原型:
void * malloc(unsigned int size);
// 函数参数 : size 为需要开辟的字节数
// 返回值 :成功 :所开辟空间的第一个字节的地址
:失败 :NULL
例: malloc(100); //开辟100字节的临时分配区域
**注意事项:**必须和女一号free函数搭配使用,否则可能发生内存泄漏.
4 女一号 free函数登场—退房的
函数功能: 释放掉动态开辟的空间(空间使用完时)
函数原型:
void free(void *p)
// 函数参数 : 需要释放释放空间的地址
// 函数返回值: 无 返回值
例: free(p); //释放指针变量p所指向的已分配的动态空间.
注意事项: 如果开完房没有用我(free)来退房,就等着内存泄漏吧
同时释放空间完成后,p任然指向那块空间,因此,我们 需要将其手动置空 P =NULL
5 男2号 calloc----连开好几间房
**函数功能:**可以在内存的动态存储区中分配n个长度为size的连续空间,这个空间一般足够大,足以保存一个数组.
函数原型:
void * calloc(unsigned n,unsigned size);
// 函数参数 : n为房间个数(变量个数) size为房间的大小(变量类型)
// 返回值: 成功 :返回开辟空间的首元素的地址
失败 :返回空
例: p=calloc(50,4); //开辟50 * 4 个字节 的临时分配区域,如果开辟成功,把首地址赋给指针变量p,如果开辟失败返回NULL.
注意事项: 如果开完房没有用我(free)来退房,就等着内存泄漏吧
6 男配角 realooc函数—重新开房
**函数功能:**malloc函数或calloc函数已经开好了房,如果想换房,我可以重新给他们开
函数原型:
void * realloc (void *p,unsigned int size);
// 函数参数: p为旧房子地址 size 为新房子的大小
// 函数返回值: 成功: 新房子的地址
失败: NULL
例:realloc(p,50); //将p所指向的已经分配的动态空间改为50字节
注意事项: 虽然我可以随时换房(修改房间大小),但是最后记得一定要用free函数来退房哦,不然有可能发生内存泄漏!
7 动态内存管理的常见错误
1 、没有检查内存是否匹配成功
2、操作内存时越界
例如:申请一个数组arr[3],如果数组引用时下标小于0或者下标大于2会发生越界。
3、使用free释放内存后,任然访问被释放内存的地址。此时应该手动将指针置空。
4、malloc与free总是成对出现的