5 years, 6 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

5 years, 6 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

Accepted Answer
5 years, 6 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 Robin Hourahane 24 Mar 2015
-deleted-
5 years, 6 months ago.

This seems really useful; what would the basic code look like?

5 years, 6 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

Thank you Paul.

posted by -deleted- 24 Mar 2015
5 years, 6 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:

Unfortunately, I have not found a reliable solution.