初学c语言20(动态内存管理)
内存分配通常分为三个区域,分别为栈区、堆区、静态区,图像如下:
栈区、静态区开辟的空间都是固定的,而堆区上可以自主开辟空间和调整空间大小
动态内存开辟有四个函数:
头文件:stdlib.h
一.mallloc
形式:
功能:向堆区申请一片连续的空间
参数:
size:要开辟空间的大小,单位为字节
返回值:
开辟成功时,返回这片空间的起始地址(类型为void*)
开辟失败时,返回空指针
所以每次开辟空间都要检查是否为空
注意:动态内存开辟的空间不会自动释放(除了整个程序结束)
当开辟空间使用完后要及时释放,不然可能会造成内存泄漏(如开辟空间后当存放该地址的指针变量被释放时,再也找不到该空间,导致开辟的空间释放不了会一直存在至整个程序结束才被销毁),所以c语言有个函数来释放堆区开辟的空间
二.free
形式:
功能:释放堆区动态内存开辟的空间(不能释放其他区域的)
参数:
ptr:开辟空间的起始地址,为空指针时什么事也不做
注意:释放后要及时将指针改为空指针,不然会变为野指针,有危险,而且不能释放内存的一部分,得从内存起始位置开始释放
应用:
三.calloc
形式:
功能:除了会将开辟的空间每个字节初始化为0其他malloc一样
参数:代表num个大小为size的元素
应用:
四.realloc
形式:
功能:调整动态内存开辟的空间
参数:
ptr:要调整内存的起始地址(必须是起始地址)
size:调整之后空间的大小,单位为字节
返回值:
调整之后的起始地址,调整失败返回空指针
realloc再调整内存空间分为俩种情况:
1.直接在原内存空间后面追加空间(原空间之后有足够的空间)
2.重新找一片连续空间,将旧空间的数据拷贝到新空间里,旧空间自动释放,所以返回的是新空间的起始地址(原空间之后没有足够的空间)
应用:
五.练习
代码:
#include <stdio.h>#include <stdlib.h>
#include <string.h>void GetMemory(char *p){p = (char *)malloc(100);}void Test(void){char *str = NULL;GetMemory(str);strcpy(str, "hello world");printf(str);}int main(){Test();return 0;}
结构和解释:
优化:
六.柔性数组
结构体最后一个成员是未知大小的数组叫做柔性数组成员
形式:
特点:
1.柔性数组成员前面至少有一个成员
2.sizeof()计算不包括柔性数组的内存
3.包含柔性数组成员的结构⽤malloc()函数进⾏内存的动态分配,并且分配的内存应该⼤于结构的⼤ ⼩,以适应柔性数组的预期⼤⼩