This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

malloc() returns valid pointer even if heap size is set to 0

Hello. I need a bit of help with my case. I have nRF52832 dev kit. I have set heap size to zero in Makefile:

nrf52832_xxaa: CFLAGS += -D__HEAP_SIZE=0
nrf52832_xxaa: CFLAGS += -D__STACK_SIZE=8192
nrf52832_xxaa: ASMFLAGS += -D__HEAP_SIZE=0
nrf52832_xxaa: ASMFLAGS += -D__STACK_SIZE=8192

And even with that change I am still able to allocate memory using malloc(). Here is the code:

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

int main(void) {
  int * p = malloc(16);

  char buf[40] = {0};
  sprintf(buf, "p: %p\r\n", p);
  SEGGER_RTT_WriteString(0, buf);
  
  while (1);

  return 0;
}

And this is the result:

p: 0x20000560

So malloc() returns valid pointer even with no heap. I have checked .map file and I can see that malloc allocates memory outside of heap.

 *(COMMON)
 COMMON         0x00000000200004ac       0xa8 _build/nrf52832_xxaa/SEGGER_RTT.c.o
                0x00000000200004ac                _SEGGER_RTT
 COMMON         0x0000000020000554        0x4 /home/era/Downloads/nordic/gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libc_nano.a(lib_a-reent.o)
                0x0000000020000554                errno
                0x0000000020000558                . = ALIGN (0x4)
                0x0000000020000558                __bss_end__ = .

.heap           0x0000000020000558        0x0
                0x0000000020000558                __HeapBase = .
                0x0000000020000558                __end__ = .
                0x0000000020000558                PROVIDE (end = .)
 *(.heap*)
 .heap          0x0000000020000558        0x0 _build/nrf52832_xxaa/gcc_startup_nrf52.S.o
                0x0000000020000558                __HeapLimit = .

.stack_dummy    0x0000000020000558     0x2000
 *(.stack*)
 .stack         0x0000000020000558     0x2000 _build/nrf52832_xxaa/gcc_startup_nrf52.S.o
                0x0000000020010000                __StackTop = (ORIGIN (RAM) + LENGTH (RAM))
                0x000000002000e000                __StackLimit = (__StackTop - SIZEOF (.stack_dummy))
                0x0000000020010000                PROVIDE (__stack = __StackTop)
                0x0000000000000001                ASSERT ((__StackLimit >= __HeapLimit), region RAM overflowed with stack)
                0x0000000000000070                DataInitFlashUsed = (__bss_start__ - __data_start__)
                0x000000000000174c                CodeFlashUsed = (__etext - ORIGIN (FLASH))
                0x00000000000017bc                TotalFlashUsed = (CodeFlashUsed + DataInitFlashUsed)
                0x0000000000000001                ASSERT ((TotalFlashUsed <= LENGTH (FLASH)), region FLASH overflowed with .data and user data)

So my first question is why malloc returns address to region that is outside of heap?

I checked how big chunk I can allocate and it seems that even if I change the malloc to allocate 1000000 bytes

int * p = malloc(1000000);

I still get the same 0x20000560 address.

The second question is why malloc() allows to allocate such a big chunk of memory? Size of RAM in nRF52832 is 64kB.

Parents Reply Children
Related