动态内存管理:涉及4个函数:malloc,free,calloc,realloc; 头文件stdlib.h;
1.malloc
void* malloc(size_t,size)向内存申请多少个字节;只知道申请多大空间,不知道存放什么类型的数据;
1.该函数向内存申请一块连续可用的空间,并返回指向这空间的指针;
2.如果开辟成功,则返回一个开辟好空间的指针; 如果开辟失败,则返回一个null指针;
3.如果size为0,是未定义的取决于编译器;
4.申请的空间在内存的堆区;函数里面的值是随机值;
这是代码演示:
2.释放空间函数:free:
void free(void* ptr)用来释放动态内存;必须从起始地址开始释放,不能从中间某一位置释放
释放完空间后,应该将指向开辟空间区域的首地址的指针改为空指针;防止变为野指针;
代码演示:
3.calloc函数
void* calloc(size_t num, size_t size) 功能:为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0;
代码演示
calloc会自动的为字节初始化0;
4.realloc再次进行调整,参数void* realloc(void* ptr, size_t size); 不会对字节进行初始化;
realloc调整空间失败会返回null;
调整成功也有两种情况:1.情况1:在已经开辟好空间的后面,没有足够的空间,直接进行空间的扩大;在这种情况下,realloc会在内存的堆区从新找一块空间(满足新的大小空间的需求),同时会把旧的数据拷贝到新空间,然后释放旧的空间,同时 返回新的空间的起始地址;没有足够大的地址;
2.情况2,在已经开辟好的空间的后面,有足够的空间直接扩大,扩大空间后,直接返回旧的空间的起始地址;有足够大的地址;
realloc函数除了能调节空间之外,还能实现跟malloc一样的功能;
malloc/calloc/realloc 申请的空间 如果不主动释放,出了作用域不会销毁的,释放的方式:1.主动释放,2.直到程序结束,才由操作系统回收;
常见的动态内存的错误
1.对NULL指针的解引用操作;2.对动态开辟空间的越界访问;3.对非动态开辟内存进行free释放;4.使用free释放一块动态开辟内存的一部分;5.对同一块空间进行多次释放;6.动态开辟内存忘记释放(内存泄漏);
柔性数组:在结构体中,最后一个成员,是未知大小的数组;
特点:1.结构中的柔性数组成员前面必须至少是一个其他成员。
2.sizeof返回的这种结构大小不包括柔性数组的内存;柔性数组前面的成员也是存在对齐规则的;
好处:1.方便内存释放;2.有利于访问速度;
对空指针进行解引用操作,程序就会崩溃; 数组是临时变量,出了函数就会被操作系统回收;返回栈空间的地址是极其危险的;