malloc函数
函数向内存申请一块连续可用的空间,返回值是一个类型为(void*)的指针,他可以转换成任何其他你要申请的内存空间。
函数原型:
void *malloc(size_t size);
- 如果开辟成功,则返回一个指向开辟好空间的指针,返回开辟好的空间的首地址;
- 如果开辟失败,则返回一个NULL指针(malloc的返回值必须做检查);
- 返回值类型是void * ,所以malloc函数并不知道开辟空间的类型,具体由使用者决定;
- 对于边界要求严的机器,malloc所返回的内存的起始位置将始终能够满足对边界对齐要求
free函数
此函数专门用来做动态内存的释放和回收;
函数原型:
void free(void * ptr);
它的参数要么是NULL,要么是malloc、calloc或relloc返回的值,若为NULL则什么都不做
free之后为野指针,再访问为非法内存。
例:申请一个长度为20个int类型元素的数组
int * ptr=(int*)malloc(20*sizeof(int));
for(int i=0;i<10;++i){
ptr[i]=i;
}
free(ptr); //如果不释放,他的生命周期是整个程序,相当于全局变量
//free之后,ptr是野指针,指向无效位置
//如果内存在动态申请,而没有及时释放,则会内存泄漏;
calloc函数
用来进行动态分配,分配num个元素,每个元素size字节
函数原型
void * calloc(size_t num,size_t size);
1. calloc为num个大小为size的元素开辟一块空间;并将申请空间全部初始化为0;
2. 与malloc的区别,calloc会在返回地址前将申请的空间每个字节初始化为0;
int main()
{
int *ptr =calloc(20,sizeof(int));
if(NULL==ptr) //判空
{
return;
}
free(ptr);
ptr=NULL; //遇到野指针手动为空
free(ptr)//空指针free没有副作用
return 0;
}
realloc函数
让动态内存管理更加灵活;
realloc函数可以做到开辟内存空间的调整;
函数原型:
void *realloc(void *ptr,size_t size);
- ptr是需要调整的内存地址;
- size是调整后的大小;
- 返回值为调整之后内存其实地址;
- 函数调整内存空间,会将原来内存中的数据移动到新的空间;
- 如果缩小一个内存块,该内存块尾部部分被拿掉,剩余部分内存的原先内容依然保留;
- 如果用于扩大一个内存块,原来空间数据不改变,新增加的内存添加到原先内存块的后面;
- 如果原先内存块无法改变大小,那么relloc将在堆空间上寻找合适大小的新空间,把原来内存块上的值复制到新的内存块上,返回值是指向新内存块的地址;
relloc函数优点 - 让动态内存管理更加灵活;
- realloc函数可以做到开辟内存空间的调整;
常见的动态内存错误:
malloc有可能失败:
动态开辟空间的越界访问;
非动态开辟内存使用free释放;
使用free释放一块动态内存开辟的一部分;
对同一块动态内存多次释放;
动态开辟内存忘记释放;