Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
9 years, 8 months ago.
How to find the amount of free space on the heap.
Hi,
Is there a call to find out how much free space there is available on the heap as I would like to check for memory leaks in my code.
Thanks
Robin
5 Answers
9 years, 8 months ago.
heapstats() and heapvalid() (double _ prefix removed due to formatting issues) will give you information about the current heap status.
Documentation is here: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0099a/armlib_cihhgjad.htm
On an LPC1768 the program
#include "mbed.h" void *ptr1; void *ptr2; int main() { fprintf(stderr,"Starting heap test\n"); __heapstats((__heapprt)fprintf,stderr); __heapvalid((__heapprt) fprintf, stderr, 1); fprintf(stderr,"\nAllocate 100 bytes\n"); ptr1 = malloc(100); __heapstats((__heapprt)fprintf,stderr); __heapvalid((__heapprt) fprintf, stderr, 1); fprintf(stderr,"\nAllocate 1024 bytes\n"); ptr2 = malloc(1024); __heapstats((__heapprt)fprintf,stderr); __heapvalid((__heapprt) fprintf, stderr, 1); fprintf(stderr,"\nFree 100 bytes\n"); free(ptr1); __heapstats((__heapprt)fprintf,stderr); __heapvalid((__heapprt) fprintf, stderr, 1); }
outputs the following to the USB serial port at 9600:
Starting heap test 4052 bytes in 1 free blocks (avge size 4052) 1 blocks 2^10+1 to 2^11 alloc block 10000354 size 18 free block 1000036c size fd4 next=00000000 ------- heap validation complete Allocate 100 bytes 3948 bytes in 1 free blocks (avge size 3948) 1 blocks 2^10+1 to 2^11 alloc block 10000354 size 18 alloc block 1000036c size 68 free block 100003d4 size f6c next=00000000 ------- heap validation complete Allocate 1024 bytes 2916 bytes in 1 free blocks (avge size 2916) 1 blocks 2^10+1 to 2^11 alloc block 10000354 size 18 alloc block 1000036c size 68 alloc block 100003d4 size 408 free block 100007dc size b64 next=00000000 ------- heap validation complete Free 100 bytes 3020 bytes in 2 free blocks (avge size 1510) 1 blocks 2^5+1 to 2^6 1 blocks 2^10+1 to 2^11 alloc block 10000354 size 18 free block 1000036c size 68 next=100007dc alloc block 100003d4 size 408 free block 100007dc size b64 next=00000000 ------- heap validation complete
9 years, 8 months ago.
Problem with checking is that the heap can be fragmented. But my preferred method is simply allocating something of a certain size on the heap, and checking the pointer value. If it keeps incrementing then you have a memory leak.
In general however you should get quite far by using malloc/new as little as possible, and when you use it always make sure there is a corresponding free/delete for every possible path your code can take.
While I have tried that in the past I've found it unreliable as you can get the same pointer back so long as you have deleted the first object but not deleted any pointers the object itself has allocated.For example if the object you new, has its own pointer that it new's but doesn't delete then you can get the same pointer back but still leaked some memory.
Is there anyway to walk the heap to find what's been allocated as this would work just as well to ensure there are no new allocations.
posted by 24 Mar 20159 years, 8 months ago.
Hi, I use the following code which I copied from a forum posting by Segundo Equipo.
// Function prototype int availableMemory(int = 256, int = 0x8000, bool = true); // Calculation function int availableMemory(int resolution, int maximum, bool disableInterrupts) { if (resolution < 1) resolution = 1; if (maximum < 0) maximum = 0; int low = 0; int high = maximum + 1; if (disableInterrupts) __disable_irq(); while (high - low > resolution) { int mid = (low + high) / 2; void* p = malloc(mid); if (p == NULL) { high = mid; } else { free(p); low = mid; } } if (disableInterrupts) __enable_irq(); return low; } // Calling the function pc.printf("\nAvailable memory = %d\n", availableMemory(1) );
My platforms are mbed LPC1768 and Arch Pro.
I make no claim to this code and cannot guarantee the algorithm is valid. I would appreciate if Erik or an mbed team member could give their opinion of the code.
Hope this is of help.
Paul
9 years, 8 months ago.
Edits applied to previous comment: I've used something quite similar to the code that Paul posted - it does a binary search for the largest single block of available space. I stress 'single' block, because fragmentation can hide leakage until it spills into the single largest block that this function would find. I came to understand that the heap is not "fixed" (as I'm used to with other embedded systems), but can dynamically flex based on stack frame (link).
I also experimented with trying to dump the allocations - but only produced something never-quite-working... It followed the allocations and showed the first X bytes of each allocation, until the parsing failed.
Off-topic slightly: Then, to complicate it more - create some threads with the OS, each with a stack frame to call its own, each of which you cannot easily determine the used, or needed, size.
Links of interest:
- https://developer.mbed.org/handbook/Memory-Model
- https://developer.mbed.org/forum/bugs-suggestions/topic/4809/
- http://developer.mbed.org/questions/2957/Is-it-possible-to-enable-exception-handl/
- http://developer.mbed.org/forum/mbed/topic/3803/?page=1#comment-24686
- https://developer.mbed.org/forum/helloworld/topic/3040/
- https://developer.mbed.org/forum/bugs-suggestions/topic/5196/
- https://developer.mbed.org/forum/bugs-suggestions/topic/3334/
Unfortunately, I have not found a reliable solution.