嵌入式系统上的malloc()行为 [英] malloc() behaviour on an embedded system

查看:208
本文介绍了嵌入式系统上的malloc()行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前工作的一个嵌入式项目(STM32F103RB,CooCox CoIDE下v.1.7.6与臂无 - EABI-GCC 4.8 2013q4),我想了解如何的malloc() 表现在普通 C 当内存已满。

I'm currently working on an embedded project (STM32F103RB, CooCox CoIDE v.1.7.6 with arm-none-eabi-gcc 4.8 2013q4) and I'm trying to understand how malloc() behaves on plain C when the RAM is full.

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

My STM32 has 20kB = 0x5000Bytes of RAM, 0x200 are used for the stack.

#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 只要堆是分配太小返回:

I would expect malloc() to return NULL as soon as the heap is too small for allocating:

0x5000处(RAM) - 0x83C (BSS) - 为0x200 (栈)= 0x45C4 (堆)

0x5000 (RAM) - 0x83C (bss) - 0x200 (stack) = 0x45C4 (heap)

所以执行的malloc()为18时。一个项目是1024 = 0x400的字节的大容量。

So when executing the malloc() for the 18th time. One item is 1024=0x400 Bytes large.

但不是的uC调用 HardFault_Handler(无效)(甚至没有 MemManager_Handler(无效)

But instead the uC calls the HardFault_Handler(void) (not even the MemManager_Handler(void))

没有任何人有一个建议如何预测一个的malloc()失败 - 因为等待 NULL 收益没有按'吨似乎工作。

Does anybody have an advice how to forecast a malloc() failure - since waiting for a NULL return doesn't seem to work.

感谢您。

推荐答案

它看起来并不像的malloc 做任何检查都没有。你得到的故障来自硬件检测到一个无效的地址,这可能是由的malloc 即将本身的写操作。

It does not look like malloc is doing any checks at all. The fault that you get comes from hardware detecting a write to an invalid address, which is probably coming from malloc itself.

的malloc 分配内存,它需要从它的内部池块,并返回给你。但是,它需要存储的免费函数的一些信息,以便能够完成释放。一般,这是该块的实际长度。为了保存这些信息,的malloc 需要从块本身的开头几个字节,写有该信息,并返回地址过去在那里写了点自己的信息。

When malloc allocates memory, it takes a chunk from its internal pool, and returns it to you. However, it needs to store some information for the free function to be able to complete deallocation. Usually, that's the actual length of the chunk. In order to save that information, malloc takes a few bytes from the beginning of the chunk itself, writes the info there, and returns you the address past the spot where it has written its own information.

例如,假设你问一个10字节的块。 的malloc 会抓住一个可用的16个字节的块,也就是说,在地址 0x3200..0x320F ,写的长度(即16)到字节1和2,并返回 0x3202 还给你。现在你的程序可以使用从 0x3202 10个字节为 0x320B 。其他四个字节是有效的,太 - 如果你调用的realloc ,并要求14个字节,就没有再分配

For example, let's say you asked for a 10-byte chunk. malloc would grab an available 16-byte chunk, say, at addresses 0x3200..0x320F, write the length (i.e. 16) into bytes 1 and 2, and return 0x3202 back to you. Now your program can use ten bytes from 0x3202 to 0x320B. The other four bytes are available, too - if you call realloc and ask for 14 bytes, there would be no reallocation.

问题的关键来当的malloc 写长成的内存块,这是即将返回你:地址到其写入的需求是有效的。看来,18次迭代后的下一个块的地址是否定的(这相当于一个非常大的正),这样的CPU陷阱的写入,并触发硬故障。

The crucial point comes when malloc writes the length into the chunk of memory that it is about to return to you: the address to which it writes needs to be valid. It appears that after the 18-th iteration the address of the next chunk is negative (which translates to a very large positive) so CPU traps the write, and triggers the hard fault.

在情况下,当堆和栈成长朝对方有来检测内存不足而让你使用的内存每个字节,这往往是一个非常理想的事情没有可靠的方法。 的malloc 不能predict你要多少堆栈分配后使用,所以它甚至没有尝试。这就是为什么在大多数情况下,字节计数是在你

In situations when the heap and the stack grow toward each other there is no reliable way to detect an out of memory while letting you use every last byte of memory, which is often a very desirable thing. malloc cannot predict how much stack you are going to use after the allocation, so it does not even try. That is why the byte counting in most cases is on you.

在一般情况下,在嵌入式硬件时的空间限制在几十千字节,避免的malloc 调用任意的地方。相反,你$使用一些pre-计算限额p $ P-分配所有内存的前期,和包裹出来给需要它的结构,从不叫的malloc 试。

In general, on embedded hardware when the space is limited to a few dozen kilobytes, you avoid malloc calls in "arbitrary" places. Instead, you pre-allocate all your memory upfront using some pre-calculated limits, and parcel it out to structures that need it, and never call malloc again.

这篇关于嵌入式系统上的malloc()行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆