动态内存:动态的创建内存,申请内存空间为变量;存放于堆(heap)区,不能通过变量名或数组名引用,只能通过指针引用
,在windows中,堆中最大的连续内存块为1.3G左右。
ANSI标准建议设有4个有关动态存储分配函数,即 malloc(), calloc(), realloc(), free(); 头文件为
#include<stdlib.h>
malloc: 从空闲内存中分配长度为size连续空间,但不初始化;
函数原型:void*malloc(unsigned size)
int *p=(int *)malloc(n*sizeof(int)); //=int p[n]
<在空闲内存中分配连续内存n*sizeof(int)个字节的堆内存空间>
返回:分配成功时返回一个指向该内存块的指针即第一个字节的地址,有时需要进行强制类型转换,内存不足时返回空指针(NULL)
生命周期:从创建到free释放;只要没有调用free函数,进程就没有结束;与free函数对称使用
calloc: 功能同malloc相同,从空闲内存中分配n个长度为size连续空间,但初始化为0<使用率低>;
函数原型:void*calloc(unsigned n,unsigned size)
int *p=(int *)calloc(n*sizeof(int));
返回:同malloc函数一样;
参数:第一个是所需开辟的内存单元数量;第二个是每一个单元的字节大小
生命周期:从创建到free释放;只要没有调用free函数,进程就没有结束;与free函数对称使用
realloc: 动态扩大或缩小申请的内存<分配新的大内存,需要更新地址>
函数原型: void * realloc(void *p,unsigned size)
p=(int*)realloc(p,20*sizeof(int))
<p为新的大小,不是扩大的大小>
返回:若申请失败返回空(NULL);但原有的内存不会发生改变
free:释放内存空间,将内释放出来给系统;解决内存泄漏问题;
函数原型:void free(void *p)
free(p);
<申请与释放是成对的,所以程序不能多次free,否则会崩溃>
free崩溃的4个原因
1、越界
#include<stdio.h>
#include<stdlib.h>
int main()
{
//int *p1=(int *)malloc(20); //error
int *p1=(int *)malloc(20*sizeof(int)); //ok
for(int i=0;i<20;i++)
{
p1[i]=0;
}
free(p1);
return 0;
}
2、指针移动,找不到头
动态内存分配内存的头部和尾部含有信息,在指针移动时字节的地址发生改变,首字节的地址被p++改变后找不到头部,
3、重复释放内存
内存的动态分配与释放是对称使用的
4、释放不是动态创建的内存