6.动态内存管理

C语言(6.动态内存管理)

1. 动态内存函数

​ 动态内存:在堆上动态的开辟内存空间

​ 动态内存函数都在头文件<stdlib.h>中声明

1.1 malloc

​ 向堆内存申请一块连续可用的空间,并返回指向这块空间的指针

void* malloc(size_t size);
  • 返回值:指向分配空间的指针,如果申请失败,返回NULL
  • 参数:size - size_t类型(unsigned int),需要申请空间的字节数

使用

int* arr = (int*)malloc(20 * sizeof(int));	//申请连续的20个int大小的空间

1.2 free

​ 释放动态开辟的内存

void free(void* ptr);
  • 返回值:无
  • 参数:ptr - 指针,被释放的空间的首地址

注意

  1. 如果参数ptr不是动态开辟的,free函数的行为是未定义的
  2. 如果ptr为NULL,则free什么也不做

使用

free(arr);		//释放arr指向的空间

1.3 calloc

​ 向堆内存为num个大小为size的元素申请一块连续可用的空间,将空间初始化为0,并返回指向这块空间的指针

void* calloc(size_t num, size_t size);
  • 返回值:指向分配空间的指针,如果申请失败,返回NULL
  • 参数
    • num - 申请的数据类型的个数
    • size - 每个数据类型的大小

注意

  1. calloc与malloc的使用区别仅仅是参数列表不同,功能上的区别仅仅是calloc会将空间初始化为0

使用

int* arr = (int*)calloc(20, sizeof(int));	//申请20个int大小的空间,并初始化为0

1.4 realloc

​ 对之前申请的内存空间,进行大小上的调整

void* realloc(void* ptr, size_t size);
  • 返回值:指向调整之后的空间的指针,调整失败返回NULL
  • 参数
    • ptr - 被调整空间的首地址
    • size - 调整后的内存字节大小

注意

  1. 原空间后面有足够的空间进行调整时,直接在原空间上追加空间,原空间的数据和调整后空间的地址不变
  2. 原空间后面的空间不足以调整到指定大小,在堆上另找一个大小合适的连续空间,并将原空间内容复制过去,新空间的地址发生改变。
  3. 如果参数是NULL,则开辟一块新空间,realloc(NULL, 40)的效果等于malloc(40)
  4. 使用relloc函数时,不要将返回值直接赋给指向空间的原指针,否则申请失败时返回NULL,导致原指针指向的内存失去指引导致内存泄漏
int* ptr = (int*)realloc(arr, 40 * sizeof(int));	//将arr重新分配40个int的大小,地址赋给ptr
if (ptr == NULL)
{
    //错误信息处理
}
arr = ptr;

2. 常见问题和解决方案

2.1 常见错误问题

  1. 内存分配未成功,却使用它

    • 解决:使用函数申请内存后,必须检查是否为NULL
  2. 内存未初始化,却使用它

    • 解决:内存申请到手之后,必须赋初始值
  3. 忘记释放,造成内存泄漏

    • 解决:动态内存的申请和释放必须配对,防止内存泄漏
  4. 内存已经释放,却仍在使用

    • 解决:释放内存后,立即将指针置为NULL,防止产生野指针
//正确写法
int* ptr = (int*)malloc(20 * sizeof(int));

//检查是申请成功
if (NULL == ptr)
{
    //错误处理
    、、、
}

//ptr初始化

//内存使用
    
free(ptr);		//释放内存
ptr = NULL;		//将ptr置为NULL
  1. realloc重新分配内存失败,原空间内存泄漏
    • realloc重新分配失败时,会返回NULL,导致直接赋值的原空间指针变成NULL,原空间失去指引
    • 解决:realloc时,先创建一个指针接收返回值,对返回值判断后再决定赋值给原空间的指针
//错误写法
ptr = (int*)realloc(ptr, 40 * sizeof(int));	//错误,失败时ptr=NULL,原空间内存泄漏

//正确写法
int* temp = (int*)realloc(ptr, 40 * sizeof(int));
if (temp == NULL)		
{
    //错误处理
}
ptr = temp;		//申请成功后,再将新地址赋值给ptr

内存泄漏:空间失去指针的指向,程序无法访问,一直存在在内存中。在程序运行结束时操作系统会回收该空间

  1. 频繁向操作系统申请空间,造成内存碎片化和程序效率低
    • 解决:使用内存池(此处不做介绍)

2.2 常见报错原因

  1. realloc报错:大概率是申请的堆内存越界访问了,realloc在重新分配内存时会先检查原来内存是否错误,如果出错就会报错
  2. free报错:大概率是申请的堆内存越界访问了,malloc申请的空间越界使用后,会在释放时报错,但NULL被free时不会报错
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值