gpt4 book ai didi

c - 嵌入式系统上的 malloc 行为

转载 作者:太空狗 更新时间:2023-10-29 16:23:28 31 4
gpt4 key购买 nike

我目前正在从事一个嵌入式项目(STM32F103RB,CooCox CoIDE v.1.7.6 with arm-none-eabi-gcc 4.8 2013q4),我正在尝试了解malloc() 当 RAM 已满时,在普通 C 上运行。

我的 STM32 有 20kB = 0x5000Bytes 的 RAM,0x200 用于堆栈。

#include <stdlib.h>
#include "stm32f10x.h"

struct list_el {
char weight[1024];
};

typedef struct list_el item;

int main(void)
{
item * curr;

// allocate until RAM is full
do {
curr = (item *)malloc(sizeof(item));
} while (curr != NULL);

// I know, free() is missing. Program is supposed to crash

return 0;
}

我希望 malloc() 在堆太小无法分配时立即返回 NULL:

0x5000(RAM)- 0x83C(bss)- 0x200(堆栈)= 0x45C4(堆)

所以当第18次执行malloc()时。一项是 1024=0x400 字节大。

但是 uC 在第 18 次之后调用了 HardFault_Handler(void)(甚至 MemManager_Handler(void) 也不行)

有没有人建议如何预测 malloc() 失败 - 因为等待 NULL 返回似乎不起作用。

谢谢。

最佳答案

看起来 malloc 根本没有进行任何检查。您遇到的错误来自硬件检测到写入无效地址,这可能来自 malloc 本身。

malloc 分配内存时,它会从其内部池中取出一 block ,并将其返回给您。但是,它需要为 free 函数存储一些信息才能完成释放。通常,这是 block 的实际长度。为了保存该信息,malloc 从 block 本身的开头获取几个字节,将信息写入那里,并返回给您它写入自己信息的位置之后的地址。

例如,假设您要求一个 10 字节的 block 。 malloc 会抓取一个可用的 16 字节 block ,比如说,在地址 0x3200..0x320F 处,将长度(即 16)写入字节 1 和 2,然后返回 0x3202 返回给你。现在您的程序可以使用从 0x32020x320B 的十个字节。其他四个字节也可用 - 如果您调用 realloc 并请求 14 个字节,则不会重新分配。

malloc 将长度写入它即将返回给您的内存块时,关键点就来了:它写入的地址必须是有效的。似乎在第 18 次迭代之后,下一个 block 的地址是负数(转化为非常大的正数),因此 CPU 捕获了写入,并触发了硬故障。

在堆和栈相互增长的情况下,没有可靠的方法来检测内存不足,同时让您使用内存的最后一个字节,这通常是非常理想的事情。 malloc 无法预测分配后您将使用多少堆栈,因此它甚至不会尝试。这就是为什么在大多数情况下字节计数都在你身上。

一般来说,在嵌入式硬件上,当空间限制在几十 KB 时,您会避免在“任意”位置调用 malloc。相反,您使用一些预先计算的限制预先分配所有内存,并将其分配给需要它的结构,并且永远不会再次调用 malloc

关于c - 嵌入式系统上的 malloc 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22422733/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com