cancel
Showing results for 
Search instead for 
Did you mean: 

Why sometimes the Heap Pointer will be pointed to 0x000000?

Lingjun Kong
Associate III
Posted on July 28, 2017 at 18:16

in my function, several heap pointers are defined like this

0690X00000607iTQAQ.png

when I comment the 111 line. the whole code works well. But when I add this line, the pointer Test_feature, ZeroCenter_Parameters, C1K,C1B will all, or sometimes partly, point to 0x000000.

eventually in 2 debug with the same code, it may different.

so the Question is:

In general, What will let the Heap pointer point to 0x00000? before free.

for my observation, the heap size is enough on my project (HEAP SIZE=0x8000, the same as stack size). I'm using STM32F746NG-Discovery Board so the RAM Space(at least 240KB for algorithm) is also enough. So it may be the problem of the IDE or Compiler?

My environment:

   KeilV523, STM32F746NG-Disco, Win10 Edu.

for more general situation. this code.

void heaptest()

{

int *a;

a=(int*)malloc(1024*4);

int i=1024;

while(i--)

{

*a=i;

//printf(''%d'',*a);

a++;

}

free(a);

}

0x08004468 BD10      POP           {r4,pc}

   176:         a=(int*)malloc(1024*4);

   177:         

0x0800446A F44F5080  MOV           r0,&sharp0x1000

   174: {

   175:         int *a;

   176:         a=(int*)malloc(1024*4);

   177:         

0x0800446E B510      PUSH          {r4,lr}

0x08004470 F000F8B6  BL.W          malloc (0x080045E0)

   178:         int i=1024;

0x08004474 F44F6180  MOV           r1,&sharp0x400

   179:         while(i--)

   180:         {

   181:                 

0x08004478 E000      B             0x0800447C

   182:                 *a=i;

   183:                 //printf(''%d'',*a);

   184:                 a++;

   185:         }

   186: 

0x0800447A C002      STM           r0!,{r1}

0x0800447C 1E49      SUBS          r1,r1,&sharp1

0x0800447E D2FC      BCS           0x0800447A

   187:                 free(a);

   188: }

   189: int main(void)

   190: {

   191:   SCB_EnableICache();

   192:   SCB_EnableDCache();

0x08004480 E8BD4010  POP           {r4,lr}

0x08004484 F7FFBF08  B.W           free (0x08004298)

before the free operation, the pointer will be pointed to 0x00000. who did that?

#c #stm32f7 #heap #c/c+ #memory #keil #c++ #keil-ide #!stm32-!heap-!sdram-!malloc
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on July 28, 2017 at 21:02

h1=(double*)malloc(576*8);

memset(h1,0,578*8);

You allocate 576 units and use 578, trashing the arena.

Your free(a) example is STILL broken, you can't advance a and pass the new pointer in.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

9 REPLIES 9
Posted on July 28, 2017 at 18:21

malloc() returns zero to indicate that the heap is out of memory.

Make the heap big enough to service your needs, see size defined in startup_stm32fxxx.s, make a localized copy in your project directory without the read-only attribute set so you can edit it.

The free() in your test case isn't being passed the pointer that was actually allocated.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 28, 2017 at 18:28

Thanks for your reply.

Yes, but I could confirm that my heap is already big enough. and the fact is, all the memory before the free() operation has been changed correctly. 

so, do you mean, if one pointer is over heap when it was malloced, all the others will be changed back to zero?

Posted on July 28, 2017 at 18:36

Calling free() with an address it didn't allocate will likely trash the memory arena.

Don't free(a += 1024);

Every time you call malloc() you need to check if it returned NULL before you attempt to use it. You should also make sure not to free(NULL). Nest your malloc/free so that failure unwinds, and doesn't compound.

>>

so, do you mean, if one pointer is over heap when it was malloced, all the others will be changed back to zero?

No, but if you take a pointer and zero memory you can trash other parts of the heap or stack if the pointer is damaged (see freeing the wrong pointer)

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 28, 2017 at 20:57

Hello!.

In function scope, every allocation with malloc (and using a local pointer) Must terminated with free(the valid pointer) before the function returns! its mandatory.

In any other case the memory will never been deallocated , until restart the program (almost like this).

Every time you call a function with 'memory leak' issue, the heap free memory decreases until all allocation functions return zero!

Posted on July 28, 2017 at 19:02

Thanks for your suggestion. I'll be carefully to malloc pointer. 

And, what do you think will make all the heap pointers be pointed to 0x00000? Because in the first code piece, I can see that the pointers has already finished its work, but be pointed to 0x0000 unknown.

And, what's more, when we trying to free a heap pointer, the pointer must be pointed to whose initial address, Is that right? 

Posted on July 28, 2017 at 19:26

I don't know what you're actually looking at, I would have the code print out the value to a console rather than have the debugger try to pull the value out of a register that may/may-not be in scope currently.

You can only free() the exact object you malloc()ed earlier, depending on the implementation this is usually not validated and will result in some form of failure, or latent failure. With memory leak/damage situations you might want to wrap the malloc/free implementation to tag memory, and catch double free and free null attempts.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 28, 2017 at 20:31

I mean, what will cause the malloc return zero? Only due to the heap is full?

I don't printf the value because of the printf function will let the result not the same. 

Just now I tried again. for the function 

void heaptest()

{

int *a;

a=(int*)malloc(1024*4);

int i=1024;

while(i--)

{

*a=i;

//printf('%d',*a);

a++;

}

free(a);

}

When there is a printf function, the 'a' will point to the initial value. and will be 0x00000 when there is no printf function. It may caused by the free() I don't know why. whatever, its not important for me.

The more important thing for me is, in another function. It seems like this

   double* A;

   A=(double*)malloc(784*8);

   double* B;

   B=(double*)malloc(784*8);

                     /*   some operation, all function   */

   free(B);

   double* h1;

   h1=(double*)malloc(576*8);

   memset(h1,0,578*8);

   double* C1K;

   double* C1B;

   C1K=(double*)malloc(25*8);

   C1B=(double*)malloc(6*8);

                           /   *some operation, all function   */

the heap this part needed is around 13 Kbytes. And free heap space is 0x8000=32 Kbytes.

The problem is:

      When malloc the C1K and C1B, it return NULL, the others work well.

      But when I comment the 'memset(h1,0,578*8);', all malloc works well.

the A B h1  get the same address with and without the memset line.

what do you think will let the C1K C1B get zero in general? Only due to the Heap Size limitation?

Posted on July 28, 2017 at 21:02

h1=(double*)malloc(576*8);

memset(h1,0,578*8);

You allocate 576 units and use 578, trashing the arena.

Your free(a) example is STILL broken, you can't advance a and pass the new pointer in.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Daniel Glasser
Associate III
Posted on July 31, 2017 at 22:13

As several people have tried to point out, the increment of the pointer 'a' in the loop changes it so that it can not be used in a call to 'free()'.

void heaptest()

{

int *a;

a=(int*)malloc(1024*4);

int i=1024;

while(i--)

{

*a=i;

//printf('%d',*a);

a++;

}

free(a);

}

Emphasis mine.  This could be rewritten as:

void heaptest(void)

{

  int* chunk = (int*)malloc(1024 * sizeof(int));

  if (chunk != NULL)

  {

    int* a = chunk;

    int i = 1024;

    while (i--)

    {

      *a = i;

      // printf('%d,\n', *a);

      a++; 

    } 

    free(chunk);

  }

}

I added a newline to the end of the format string in the commented out 'printf()' call.