STM32开发中malloc使用与heap_size配置故障排查
STM32 ARM-M4 动态内存调试问题解答
问题背景
我基于ST的ARM-M4芯片开发程序,移植了一款网络库后发现,必须把.s启动文件里的heap_size增大到0x400程序才不会崩溃。我已经把系统malloc接口替换成了自定义的mymalloc,但查看.map链接文件时还是发现部分文件引用了malloc,却找不到具体的调用代码行。
我的问题
- 在ST的MDK环境中,有没有更优的方法判断系统
malloc函数是否被调用?比如能不能在线设置断点? - STM32的.s启动文件中的
heap_size除了给malloc等动态内存分配函数用,还有其他用途吗? - 除了
malloc相关的动态内存分配函数外,还有哪些系统库函数可能会调用malloc?
我的尝试
- 在头文件顶部用
#define malloc mymalloc替换系统malloc; - 通过库的
malloc接口将系统malloc替换为自定义实现。
问题解答
1. MDK中判断系统malloc是否被调用的方法
- 直接设置断点拦截:在MDK调试界面,直接在
malloc函数上设置断点。如果是标准库的malloc,可以在stdlib.h中找到其声明,右键选择「Set Breakpoint」;调试时打开「Call Stack + Locals」窗口,程序触发malloc时会自动暂停,通过调用栈就能定位到具体的代码调用行。 - 覆盖系统malloc实现:如果找不到标准
malloc的源码,可在工程中新建C文件,实现一个临时的malloc函数:
编译时这个自定义实现会覆盖标准库版本,一旦有代码调用void* malloc(size_t size) { __BKPT(0); // 触发硬件断点 return NULL; }malloc就会触发断点,直接定位调用位置。 - 符号搜索+反汇编定位:在MDK的「View」菜单打开「Symbol Window」,搜索
malloc查看引用该符号的目标文件,对这些文件右键选择「Disassemble」,从汇编代码中找到调用malloc的位置,再对应到C代码行。
2. STM32启动文件中heap_size的其他用途
启动文件里的heap_size主要服务于C标准库的动态内存分配体系,除malloc、calloc、realloc等函数外,还有这些场景会用到:
- C++对象堆构造:若工程包含C++代码,用
new关键字创建堆上对象时,会直接依赖这块heap空间。 - 标准库隐式内存分配:部分标准库函数会在内部动态申请内存,比如
printf处理复杂格式化时的临时缓冲区、strtok_r的内部状态存储、部分字符串操作函数的临时空间。 - RTOS默认内存池(若使用RTOS):部分RTOS默认会用系统heap创建任务、队列等对象,不过多数RTOS支持配置自定义内存池,此时就与启动文件的heap无关。
3. 会调用malloc的系统库函数举例
除malloc、calloc、realloc、free等直接内存函数外,很多标准库函数会隐式调用malloc,常见的有:
- 字符串处理类:
strdup(复制字符串时申请内存)、asprintf(格式化字符串并分配内存)。 - IO相关类:
fopen(部分实现会为文件结构体分配内存)、tmpfile(创建临时文件时申请内存)。 - 工具函数类:
qsort(部分实现会申请临时缓冲区)、getaddrinfo(存储地址信息时申请内存)。 - 网络库相关:你移植的网络库大概率会通过标准
malloc申请缓冲区,标准库的网络相关函数也可能隐式调用malloc。 - C++相关:
new操作符底层依赖malloc,STL容器(如std::vector、std::string)扩容时也会调用malloc。
内容的提问来源于stack exchange,提问作者kanghao chen
相关产品推荐
相关产品推荐

