什么是动态内存的申请和释放?
当程序运行到需要一个动态分配的变量时,必须向系统申请取得堆中的一块所需大小的存储空间,用于存储该变量。当不再使用该变量时,也就是它的生命结束时,要显式释放它所占用的存储空间,这样系统就能对该堆空间进行再次分配,做到重复使用有限的资源。
1.malloc函数
在C语言中,使用malloc函数来申请内存。函数原型如下:
#include<stdlib.h>
void *malloc(size_t size);
参数size代表需要动态申请的内存的字节数,若内存申请成功,函数返回申请到的内存的起始地址,若申请失败,返回NULL
int *p = (int *)malloc(10*sizeof(int));
需注意:
1.只关心申请内存的大小,单位是字节
2.申请的是一块连续的内存,该函数一定是申请一块连续的区间若申请失败,则返回NULL
3.初始化,注意:堆区是不会自动在分配时做初始化的(包括清零),所以程序中需要初始化
2.free 函数
在堆区上分配的内存,需要用free函数显示释放。函数原型如下:
#include <stdlib.h>
void free(void *ptr);
函数的参数ptr,指的是需要释放的内存的起始地址。该函数没有返回值。
{
int *p = (int *)malloc(10*sizeof(int));
free(p);
}
需注意:
1.必须提供内存的起始地址。调用该函数时,必须提供内存的起始地址,不能提供部分地址,释放内存中的一部分是不允许的。因此,必须保存好malloc返回的指针值,若丢失,则所分配的堆空间无法回收,称内存泄漏。
2.malloc和free配对使用。编译器不负责动态内存的释放,需要程序员显示释放。因此,malloc与free是配对使用的,避免内存泄漏。
free崩溃的原因:
1、越界.漏写sizeof,realloc第二个参数写错
2、修改了指针的指向,p++
3、重复释放同一段内存
4、释放非动态内存
int main()//free崩溃情景1
{
int *p = (int *)malloc(10*sizeof(int));
for(int i=0;i<=10;i++)
{
p[i] = 0;
}
free(p);
return 0;
}
3.calloc 函数
4.realloc 函数
函数原型如下:
#include <stdlib.h>
void *realloc(void *mem_address, unsigned int newsize);
先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。