目录
1.定义
所谓动态内存分配(Dynamic Memory Allocation)就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不像数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求的大小。
2.函数分类
【使用内存分配函数时添加头文件#include<stdlib.h>】
2.1 malloc
2.1.1函数原型分析
//函数原型
void *malloc(unsigned int size)
//其中void* 表示malloc返回的内存空间类型未知,需要程序员根据自己的需要进行设计
//size表示空间长度为size
//该函数返回所申请空间的起始地址,需要用对应的指针进行接收
2.1.2 利用函数申请空间
//[进行申请]
//(以申请int类型的长度为40字节的内存空间为例)
int* p=(int*)malloc(40)
//【注】40字节的int类型——10个int
2.1.3 进行检验(可能会出现未分配内存空间的情况)
if(p==NULL){
printf("%s\n",strerror(errno));
return 1;
}
2.1.4 使用分配的内存空间
//[进行存放]
int i=0;
for(i=0;i<10;i++){
*(p+i)=i+1;
}
//[进行打印]
for(i=0;i<10;i++){
printf("%d ",*(p+i));
}
2.2 free
由动态内存的定义知,动态内存的分配不仅包含分配空间,同时还包含回收空间。
我们使用free( )函数进行空间的回收。
//[释放内存]
free(p);//释放p指向的空间
p=NULL;//将p指针赋值为空
2.3 calloc
//函数原型
void* calloc(unsigned int num,unsigned int size);
//在内存的动态存储区中分配num个长度为size的连续空间
2.3.1 利用函数申请空间并进行检验
int* p=(int*)calloc(10,sizeof(int));
//申请了10个int类型的空间
if(p==NULL){
perror("calloc");
return 1;
}
2.3.2 使用空间并释放
//使用
int i=0;
for(i=0;i<10;i++){
printf("%d ",*(p+i));
}
//释放
free(p);
p=NULL;
【注意!】此处使用calloc函数申请空间后,在未对内存空间赋值的情况下直接打印空间内的值,结果为0。
这是因为calloc申请好空间后,会将空间初始化为0,返回起始地址;
而malloc函数在申请好空间后,会直接返回起始地址,所以在2.1.4中我们需要先在内存中存放数据,然后再打印空间中的数据。
2.4 realloc
特点:让动态内存管理更加灵活,可以对已开辟的空间进行扩容
//函数原型
void* realloc(void* ptr,size_t size);
//ptr指向之前被realloc,malloc,calloc开辟的空间
//size指新开辟空间的大小
2.4.1 使用malloc函数开辟空间并使用
int *p=(int*)malloc(5*sizeof(int));
//5*sizeof(int)表示开辟5个int类型的空间
//等同于:int* p=(int*)malloc(20);
if(p==NULL){
perror("malloc");
return 1;
}
//使用malloc开辟的空间
int i=0;
for(i=0;i<5;i++){
*(p+i)=1;
}
2.4.2 使用realloc函数进行扩容
//需要增容10个新的空间
int* ptr=(int*)realloc(p,10*sizeof(int));
【注意!】扩容分为两种类型:原地扩容(红色标识)、异地扩容(黄色标识)
为满足以上两种情况,空间重分配成功后旧内存会被自动释放,旧指针变成了野指针 。
因此,可以将扩容后的新指针(ptr)赋给旧指针(p),即旧指针(p)指向已扩容完成的新空间。
//如果空间开辟成功
if(ptr!=NULL){
p=ptr;
}
//打印增容的空间元素
for(i=0;i<10;i++){
printf("%d ",*(p+i));
}
free(p);
p=NULL;
结果如下图所示:
可知此时已开辟的存放int类型元素的空间中,前5个元素仍未1,其余5个元素未被初始化。
对空间进行赋值
//使用增容的空间
for(int i=0;i<10;i++){
*(p+i)=i;
}
结果如下图所示:
2.4.3 realloc申请内存
realloc除了对已开辟的空间进行扩容外,还可以直接开辟空间。功能相当于malloc。
int* p=(int*)realloc(NULL,40);
//40指开辟40个字节用于存放int类型的元素
//等同于 int* p=(int *)realloc(NULL,sizeof(int)*10);
3.小结
至此,动态内存分配的四种函数已经介绍完成,下面通过一个图表比较它们的异同。
函数 | 作用 | 是否初始化元素 |
malloc | 开辟size个字节的内存空间 | 否 |
calloc | 开辟num个可以存放x类型的内存空间 | 是 |
realloc | 1.对已经开辟的空间进行扩容 2.直接开辟size个字节的内存空间 | 否 |
free | 释放已开辟的内存空间 | / |
下一期将分析动态内存开辟时易遇到的问题。