0

I know that malloc () is an over allowing and free () does not release the entire memory. I test a code that checks all this:

extern char _end;
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{

    char * res;
int tas,rupt,esp;
printf("\n Before any memory reservation\n --------------------------\n");
tas=sbrk(0);
printf("End position of the pile : %p\n",tas);
rupt=&_end;
printf("Breaking point : %p\n",rupt);
esp=tas-rupt;
printf("Space between the end of the heap and breaking point : %d bytes \n",esp);
printf("Pages allocated for malloc %f\n",(tas-rupt-esp)/4096.0);
printf("whether %d bytes\n",tas-rupt-esp);



int nbEntier = 0, i = 0;
int* tabEntier ; // This pointer is used as a table after the call of malloc

// Asked the number of integers to the user
printf("How integer do you want to store? ");
scanf("%d", &nbEntier);

if (nbEntier > 0) 
{
    tabEntier = malloc(nbEntier  * sizeof(int));  
    if (tabEntier== 0) 
    {
        exit(0); // 
    }

    //We ask the integer
    for (i = 0 ; i < nbEntier  ; i++)
    {
        printf("Integer n° %d ? ", i + 1);
        scanf("%d", &tabEntier[i]);
    }

    // We display the integer one to one
    printf("\n\nYour integers are :\n");
    for (i = 0 ; i < nbEntier  ; i++)
    {
        printf("%d \n", tabEntier[i]);
    }
tas=sbrk(0);
printf("End position of the pile : %p\n",tas);
rupt=&_end;
printf("Breaking point : %p\n",rupt);
printf("Space between the end of the heap and breaking point : %d bytes \n",tas-rupt);
printf("Pages allocated for malloc %f\n",(tas-rupt-esp)/4096.0);
printf("whether %d bytes\n",tas-rupt-esp);

    free(tabEntier);


    printf("\nDisplay after free ():\n");


     printf("\n\nYour integers are :\n");
    for (i = 0 ; i < nbEntier  ; i++)
    {
        printf("%d \n", tabEntier[i]);
    }



}

return 0;
}

My result:

Before any memory reservation
--------------------------
End position of the pile : 0x9886000
Breaking point : 0x8049c2c
Space between the end of the heap and breaking point : 25412564 bytes 
Pages allocated for malloc 0.000000 
whether 0 bytes
How integer do you want to store? 3
Integer n° 1 ? 45
Integer n° 2 ? 85
Integer n° 3 ? 78


Your integers are :
45 
85 
78 
End position of the pile : 0x98a7000
Breaking point : 0x8049c2c
Space between the end of the heap and breaking point : 25547732 bytes 
Pages allocated for malloc 33.000000
whether 135168 bytes

Display after free ():


Your integers are :
0 
85 
78

I don't understand! It allocates 33 page all the time even if I ask a integer and also why after free () it releases the entire first and not the rest ..

Martin Liversage
  • 104,481
  • 22
  • 209
  • 256

1 Answers1

4

A computer frees memory by forgetting what is stored in a memory cell. When you type free(), you simple tell the heap management that nothing of interest is stored at that address, and that the memory cells aren't reserved any longer. So there is no such thing as "erasing" a memory cell, no code will be executed that actively writes zero to it.

In your specific case, you call free() and tell it that 3xsizeof(int) bytes are free to be used by the rest of the program. Some other part of the program needed to store the value 0 somewhere, and it just happened to be in the cell you had previously reserved.

Generally, printing the contents of a pointer that has been passed to free() is undefined behavior. Anything can happen. To dwell on why a undefined behavior acts in a certain way, in a certain program for a certain compiler, is pointless knowledge. Simply accept that the memory cells cannot be trusted after the free() call, and that's enough.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 1
    strongly related is also [this epic answer](http://stackoverflow.com/a/6445794/1025391). – moooeeeep May 07 '12 at 11:51
  • First sentence is quite incorrect - it does not forget what's stored there. That's why 85 and 78 are popping back again. – Agent_L May 07 '12 at 11:55
  • @Agent_L Well, it is a definition what you mean with "computer". Your program and your CPU has certainly forgotten all about it, there is no reference to the data remaining. The RAM cells have not forgotten. Had it been some old, crappy RAM from ancient days, I suppose the computer would have been free to skip the voltage refresh of the cells, and then you would just get random junk if you tried to read them. – Lundin May 07 '12 at 12:00
  • @Lundin Yeah, I know what you meant. But the memory has two levels : one information is the content stored in the memory and another is what's taken and what's free. The confusion between those 2 is the main problem here. I meant that "forgetting what is stored in a memory cell" one might interpret as "forgetting the data stored in a memory cell". Clearly, Moshab already did that mistake and humans have strong tendency to interpret smallest ambiguity according to previous (wrong) assumptions. – Agent_L May 07 '12 at 12:44
  • Ok I understood for the free (). Now I wonder if after a free () can I still use non-reserved memory? how? Is it available for system? – Moshab Flex May 07 '12 at 13:23
  • @MoshabFlex You cannot use that memory directly with a pointer, as in your example. Instead, you have to request more memory through another call to malloc(). Those cells are part of the heap, all access has to go through malloc(), because it does not only reserve memory, it also handles things like segmentation: it finds the most suitable chunk of adjacent memory with the requested size. – Lundin May 07 '12 at 13:49