前言:
基于本人回顾与思考撰写,仅供学习参考......
1.0 为什么使用动态内存
typedef struct
{
uint8_t paramType;
uint8_t value[100];
uint32_t size;
} CfgParam;
static CfgParam g_cfgParam;
g_cfgParam.paramType = 1;
g_cfgParam.value[0] = 0x9A;
g_cfgParam.value[1] = 0x99;
g_cfgParam.value[2] = 0x99;
g_cfgParam.value[3] = 0x3F;
g_cfgParam.size = 4;
在这个例子中,结构体用来管理接收到的网络数据,比如温度校准系数、PM2.5阈值等等,实际数据保存在value数组里;
如果只有极少数场景,接收到的网络数据量很大,比如接近100字节;但是绝大部分场景,只有几个字节,此时使用大数组是不合理的,浪费内存空间
C语言提供了一种灵活的方案,在程序运行期间可以动态的申请和使用内存。
2.0 申请动态内存
申请动态内存
#include <stdlib.h>
void *malloc(unsigned int size)
malloc是动态内存分配函数,用于在堆上申请一块指定大小的连续内存区域,单位是字节,申请成功返回分配区域的起始地址,分配失败返回NULL(数值为0);
返回结果是void*,需要强制类型转换为自己需要的类型。
3.0 动态内存使用
uint8 t *p = (uint8 t *)malloc(4);
通过malloc申请4个字节的内存空间,使用uint8t*强制类型转换,表示可以使用uint8 t类型去解释和管理这段内存空间。
p[0] = 0x01;
p[1] = 0x02;
p[2] = 0x03;
p[3]= 0x04;
如果堆上可用的内存空间不足时,会申请失败,返回NULL,但是在编译阶段是发现不了这种问题的
申请失败处理
4.0 动态内存释放
uint8_t *p= (uint8 t *)malloc(4);
......
free(p);
开辟动态内存不释放会有什么后果,开辟动态内存不进行释放,会导致再次开启动态内存失败
int main(void)
{
uint8_t *p = (uint8_t *)malloc(3000);
if (p == NULL)
{
printf("malloc for p failed\n");
return -1;
}
p[0] = 0x01;
p[1] = 0x02;
uint8_t *m = (uint8_t *)malloc(3000);
if (m == NULL)
{
printf("malloc for m failed\n");
return -1;
}
return 0;
}
开启不释放动态内存会导致动态内存开启失败
针对的是 p 本身:这里 p 是一个指针变量,它指向一块动态分配的内存。
将它保存的地址值设置为 0:在释放内存后,将指针 p 的值设置为 NULL(即 0),表示该指针不再指向任何有效的内存地址。
避免野指针:如果在释放内存后不将指针设置为 NULL,那么该指针仍然指向一个已经被释放的内存地址。这种情况下,如果后续代码尝试通过该指针访问内存,可能会导致未定义行为,甚至程序崩溃。这种指向无效内存地址的指针被称为“野指针”。
int main(void)
{
uint8_t *p = (uint8_t *)malloc(3000);
if (p == NULL)
{
printf("malloc for p failed\n");
return -1;
}
p[0] = 0x01;
p[1] = 0x02;
// 释放动态内存
free(p);
// 将指针设置为NULL
p = NULL;
uint8_t *m = (uint8_t *)malloc(3000);
if (m == NULL)
{
printf("malloc for m failed\n");
return -1;
}
return 0;
}
野指针:表示指针变量保存的地址值是非法的
注:----------------------------------------------------------------------------|-------------------------------------------
定义指针变量时,如果不能马上赋值,初始化为NULL; |
针对动态内存,free()后,需要将指针变量赋值为NULL; |
-----------------------------------------------------------------------------------|------------------------------------------
5.0 生命周期
申请的动态内存空间不会随着函数结束而被主动释放掉,所以在函数外部可以使用,同样使用完需要free()和设置为NULL。
后记:
......
标签:malloc,cfgParam,uint8,动态内存,NULL,指针 From: https://blog.csdn.net/qq_45973003/article/details/144261919