2017-07-28 09:16 AM
in my function, several heap pointers are defined like this
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-!mallocSolved! Go to Solution.
2017-07-28 02:02 PM
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.
2017-07-28 09:21 AM
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.
2017-07-28 11:28 AM
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?
2017-07-28 11:36 AM
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)
2017-07-28 11:57 AM
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!
2017-07-28 12:02 PM
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?
2017-07-28 12:26 PM
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.
2017-07-28 01:31 PM
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?
2017-07-28 02:02 PM
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.
2017-07-31 01:13 PM
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.