How to check for RAM available?

29 Mar 2011

I've published a program here: http://mbed.org/users/Kemp/programs/memory_test/

Unless I messed up when typing it out, this demonstrates the crash on memory allocation (without returning NULL or causing a hard fault).

29 Mar 2011

On a related note, if you add up the allocations and the statically used RAM, it crashes out once it hits about 22kB used.

29 Jan 2015

Has we finally sorted out this problem? I tested John's code today with the latest mbed compiler. It is still crash without return to NULL or causing hard_fault.

John Kemp wrote:

On a related note, if you add up the allocations and the statically used RAM, it crashes out once it hits about 22kB used.

29 Jan 2015

Moved the issue to github. https://github.com/mbedmicro/BLE_API/issues/26 I'll look into it within a couple of weeks. I'll be away from work next week.

13 May 2015

I've recently run into a memory issue and while researching ideas I came across this topic. I compiled John's program to see if it can shed light on my crashes when dealing with strings as I'm crashing with string concatenations (assuming a bad malloc()).

John Kemp wrote:

On a related note, if you add up the allocations and the statically used RAM, it crashes out once it hits about 22kB used.

I used your program and modified a few parameters to see if only 22kB is used is the correct assumption. I tried a few different variable combinations and came up with this table.

*ptr	int size	char size	index	memory used	
4		0			1			3432	17160		Busout removed	*27456 corrected for 8 byte structure
4		0			1			3404	17020						*27232
4		0			0			3404	13616						*27232		
4		4			0			3404	27232		
4		4			14			1135	24970		
4		4			28			687		24732		Busout removed
4		4			28			682		24552
4		4			40			568		27264		
4		4			80			309		27192		
4		4			120			212		27136		
4		4			180			141		26508
4		4			190			135		26730
4		4			200			130		27040		Busout removed
4		4			200			129		26832
4		4			208			124		26784
4		4			210			120		26160
4		4			220			116		26448
4		4			260			99		26532
4		4			300			86		26488
4		4			400			65		26520

From what the table shows the more the while-loop runs the faster the heap and stack crash together.

Memory used = (*ptr+int+char)*index

It also makes since that the hard fault isn't triggers as from what I have read those are disabled with the online compiler. So I removed it from the code.

The final modified code is:

#include "mbed.h"
 
 
Serial pc(USBTX, USBRX);

void fail()
{
    pc.printf("Caught the failure\r\n");    
}
 
 
class Test
{
    public:
        int something;
        char woot[200];
};
 
 
int main() {
    pc.baud(921600);
    Test *dummy;
    int index = 0;
    
    while(1) {
        dummy = new Test;
        if (dummy == NULL) fail();
        pc.printf("%u\r\n", index++);
    }
}
  • Edit - Sort of off topic... but I did some testing and It seems the smallest structure is 8 bytes. If this is used an anomaly can be seen where 8 extra bytes go missing.

Empty Structure is 8 (ptr and NULL, 3 byte pad)			
Index	Address		malloc too big	delta index
494		268440464	16				494
1006	268444568	16				512
1518	268448672	16				512
2030	268452776	16				512
2542	268456880	16				512
2991	268460480	16				449
3215	268462280	16				224
3327	268463184	16				112
3382	268463632	16				55
3409	268463856	16				27
3422	268463968	16				13
3428	268464024	16				6
3431	268464056	16				3
14 Jan 2016

John Kemp wrote:

I've published a program here: http://mbed.org/users/Kemp/programs/memory_test/

Unless I messed up when typing it out, this demonstrates the crash on memory allocation (without returning NULL or causing a hard fault).

The test program does what is expected. operator new will never return NULL except when it is called with std::no_throw. So, in this case, when there is no memory left, new will call std::abort which will call HardFaulthandler.

So, if you want that new return NULL when there is no memory left, use the nothrow version of the operator.

nothrow usage

#include <new>

// will return NULL if there is no memory left instead of calling std::abort
Foo* foo = new(std::nothrow) Foo;