本文章以
ESP32
为依托,旨在解决在【嵌入式工程】开发过程中,在动态申请内存这部分,由于malloc
之后,忘记free
释放,造成内存溢出导致MCU
重启的问题
📋 个人简介
- 💖 作者简介:大家好,我是喜欢记录零碎知识点的菜鸟打工人。😎
- 📝 个人主页:欢迎访问我的 Ethernet_Comm 博客主页🔥
- 🎉 支持我:点赞👍+收藏⭐️+留言📝
- 📣 系列专栏:物联网开发ESP32 🍁
- 💬格言:写文档啊不是写文章,重要的还是直白!🔥
目录
- 1. 模拟 malloc 不 free 的现象
- 2. 带 log 记录的 malloc 方式
- 2.1 功能描述
- 2.2 只申请不释放,申请失败时会打印 log 数组中的信息
- 2.3 申请后及时释放,不报错误
- 3. 代码展示
1. 模拟 malloc 不 free 的现象
场景:在 main
函数中只申请内存,不释放内存,并监控内存剩余量
现象:内存申请完毕后,MCU
就重启了
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "nvs_flash.h"void app_main(void)
{esp_err_t err = nvs_flash_init();if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {ESP_ERROR_CHECK(nvs_flash_erase());err = nvs_flash_init();printf("nvs_flash_init");}char *queue;while (1){queue = malloc(10000);queue[0] = 12;vTaskDelay( 100 / portTICK_PERIOD_MS);ESP_LOGI("app_main:test malloc not free", "[APP] Free memory: %d bytes", esp_get_free_heap_size());} }
若在 malloc
之后及时free
,则没有问题
但是再有经验的人也会有犯错误的时候。
2. 带 log 记录的 malloc 方式
参考:嵌入式开发正确使用动态内存的方法
正确使用动态分配内存
调试过程中发现
在此基础上,自己增加了以下内容
-
_dmem_log
结构体增加funcName
,用于记录动态分配内存的函数名称 -
log 日志数组初始化
-
MallocExt()
函数接口增加fun
参数 -
当
MallocExt()
失败时,增加打印 log 日志记录的功能
2.1 功能描述
#define DMEM_DBG 1
打开debug
调试开关
- 当关闭
debug
开关时,MallocExt()
和FreeExt()
函数与malloc()
和free()
是等价的 - 当打开
debug
开关时,开启malloc
日志记录功能
- 定义一个结构体数组
s_astDMemLogp[20]
用于存储每一次 malloc 分配的信息,主要包含 分配的大小和函数名 - 在 debug 模式下,
MallocExt()
都会调用LogDMem()
记录malloc
的信息 - 当内存不够用时,则
malloc
失败,则会打印 上20次malloc
的信息用于查找问题出现的原因
2.2 只申请不释放,申请失败时会打印 log 数组中的信息
只申请不释放,申请失败时会打印 log 数组中的信息
测试代码:
#include <stdio.h>#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "nvs_flash.h"
#include "esp_vfs_fat.h"#include "debug.h"void test_func1()
{char *queue;queue = MallocExt (11111,"test_func1");
}void test_func2()
{char *queue;queue = MallocExt (22222,"test_func2");
} void app_main(void)
{esp_err_t err = nvs_flash_init();if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {ESP_ERROR_CHECK(nvs_flash_erase());err = nvs_flash_init();printf("nvs_flash_init");}char *queue;while (1){queue = MallocExt (10000,"app_main");queue[0] = 12;test_func1();test_func2();//FreeExt(queue);vTaskDelay( 500 / portTICK_PERIOD_MS);ESP_LOGI("app_main:test malloc not free", "[APP] Free memory: %d bytes", esp_get_free_heap_size());}
}
2.3 申请后及时释放,不报错误
3. 代码展示
代码请到 csdn 下载
没有积分的同学,请点赞收藏,私信留言