任何动态内存函数的存储位置都是在堆区
1. 为什么要有动态内存分配
方便程序运行时,根据需求动态改变需要开辟的空间
2. malloc 和 calloc
malloc和calloc函数都是用来分配动态内存的
两者的区别是格式不同,calloc函数在开辟空间时,会先将该空间的数据初始化为0;
而malloc函数则是单纯的开辟空间。
2.1 malloc
格式:void* malloc(size_t size)
int num;
scanf("%d",&num);
//根据需要来开辟空间
int* p = NULL;
p = (int* )malloc(num * sizeof(int))
malloc函数返回的是地址。若是malloc开辟空间失败,则会返回空指针。因此使用malloc函数时需要判断是否为空指针。
同时,因为返回的是void*的指针,具体在分配空间时,需要根据使用的对象转换类型。
2.2 calloc
格式:void* calloc(size_t num,size_t size)
int num;
scanf("%d",&num);
//根据需要来开辟空间
int* p = NULL;
p = (int* )calloc(num , sizeof(int))
3. free 和 realloc
3.1 free函数
free函数是专门用来释放和回收动态内存的。
格式;void free(*p)
int num;
scanf("%d",&num);
//根据需要来增大空间
int* p = NULL;
p = (int* )malloc(num * sizeof(int))
free(p);//释放内存
p = NULL;//当指针p的内存释放后,p就成了野指针。必须将p设为空指针,防止野指针影响整个程序。
注意:
若free函数指向的内存不是动态内存,那么free函数的行为是未定义的;
若free函数指向的p为空指针,那么free函数什么都不做
3.2 realloc函数
realloc函数是用来改变动态内存的大小的
格式:void* realloc(void* p,size_t size)
p是需要调整的内存,size是调整之后的大小
int num;
scanf("%d",&num);
//根据需要来增大空间
int* p = NULL;
p = (int* )malloc(num * sizeof(int))
p = (int* )realloc(p,10 * size_t(int))
free(p);
p = NULL;
在扩大空间时,有两种情况
① 在原有空间的位置向后,有足够的空间
在原有空间的基础上,向后开辟空间,并且返回这个空间的地址
② 在原有空间的位置向后,没有足够的空间
在堆区寻找一块新的空间,并且在新的空间里移植原有的数据,之后返回新空间的地址
4. 柔性数组(flexible array)
柔性数组(flexible array)是指C99允许结构中的最后一个元素是未知大小的数组。
例如:
#include<stdio.h>
int main()
{
typedef struct st_type
{
int i;
int a[0];
}type_a;
}
4.1 柔性数组的特点:
① 结构中的柔性数组成员前面必须至少有一个其他成员。
② sizeof 返回的这种结构大小不包括柔性数组的内存。
③ 包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
例如:
4.2 柔性数组的优势