-1

I need to write an assignement regarding how memory managment is implemented in order to understand what do the few non-zero numbers in the output of this code represent.

I do know that the malloc() function reserves a block of memory of the specified number of bytes. And, it returns a pointer of type void which can be casted into pointer of any form. I also know that if the dynamically allocated memory is insufficient or more than required, you can change the size of previously allocated memory using realloc() function.

Here is the code I have to analyze:

#include <stdlib.h>
#include <stdio.h>

/*** Just playing with the malloc(), realloc(), free()
 *** in order to guess how memory management
 *** is implemented on this machine. If you get SEGMENTATION
 *** FAULT while addressing unallocated memory, just run
 *** the program with different "min" and/or "max" values,
 *** explicitly given on the command line through argv[]
 *** NOTICE: the default values are appropriate for the 32bit systems
 *** available in the labs ***/


void showmem (unsigned char *ptr, int min, int max, char name) {
    int i;
    for (i = min; i < 0; i++)           
      printf ("%hhu ",ptr[i]);          
    printf ("*%c=%hhu ",name,*ptr);     
    for (i = 1; i <= max; i++)          
      printf ("%hhu ",ptr[i]);
    printf ("\n\n");
}


int main(int argc, char**argv) {
    unsigned char *p, *q, *o;
    int sz=1, min=-8, max=60;

    if ( argc > 1 )             
        sscanf(argv[1],"%d",&sz);       
    if ( sz <= 0 )
        sz = 1;
    else if ( sz > 300 )
        sz = 300;
    if ( argc > 2 )             
        sscanf(argv[2],"%d",&min);
    if ( min > -1 )
        min = -1;
    else if ( min < -50 )
        min = -50;
    if ( argc > 3 )             
        sscanf(argv[3],"%d",&max);
    if ( max < sz )
        max = sz;
    else if ( max > (sz+100) )
        max = sz+100;

    printf("... allocating %d bytes to p[] (show memory from p[%d] to p[%d])\n\n",sz,min,max);
    p = (unsigned char*)malloc(sz);     
    if ( p == NULL ) {
        perror ("Error allocating p\n");
        return -1;
    }
    showmem (p,min,max,'p');

    printf("... allocating %d bytes to q[]\n\n",sz);
    q = (unsigned char*)malloc(sz);     
    if ( q == NULL ) {
        perror ("Error allocating q\n");
        return -1;
    }
    showmem (p,min,max,'p');
    showmem (q,min,max,'q');

    sz += 10;                   
    printf("... reallocating p[] to %d bytes (show old p[], new p[], and q[])\n\n",sz);
    o = p;
    p = (unsigned char*)realloc((void*)p,sz);   
    showmem (o,min,max,'o');
    showmem (p,min,max,'p');
    showmem (q,min,max,'q');

    sz += 15;                   
    printf("... reallocating p[] to %d bytes\n\n",sz);
    p = (unsigned char*)realloc((void*)p,sz);   //void e' l'indirizzo di memoria. sz e' la nuova dimensione
    showmem (o,min,max,'o');
    showmem (q,min,max,'q');
    showmem (p,min,max,'p');

    sz -= 25;                   
    printf("... reallocating p[] to %d bytes\n\n",sz);
    p = (unsigned char*)realloc((void*)p,sz);
    showmem (o,min,max,'o');
    showmem (q,min,max,'q');
    showmem (p,min,max,'p');

    printf("... freeing p\n\n");
    free((void*)p);     `       
    showmem (o,min,max,'o');
    showmem (q,min,max,'q');
    showmem (p,min,max,'p');

    printf("... freeing q\n\n");
    free((void*)q);
    showmem (o,min,max,'o');
    showmem (q,min,max,'q');
    showmem (p,min,max,'p');

    printf("... freeing old p\n\n");
    free((void*)o);
    showmem (o,min,max,'o');
    showmem (q,min,max,'q');
    showmem (p,min,max,'p');

    return 0;

}

And here is the ouput compiling the file without any other inputs:


... allocating 1 bytes to p[] (show memory from p[-8] to p[60])

33 0 0 0 0 0 0 0 *p=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 129 253 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

... allocating 1 bytes to q[]

33 0 0 0 0 0 0 0 *p=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 97 253 1 0 0 

33 0 0 0 0 0 0 0 *q=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 97 253 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

... reallocating p[] to 11 bytes (show old p[], new p[], and q[])

33 0 0 0 0 0 0 0 *o=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 97 253 1 0 0 

33 0 0 0 0 0 0 0 *p=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 97 253 1 0 0 

33 0 0 0 0 0 0 0 *q=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 97 253 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

... reallocating p[] to 26 bytes

33 0 0 0 0 0 0 0 *o=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 0 0 0 0 

33 0 0 0 0 0 0 0 *q=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

49 0 0 0 0 0 0 0 *p=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 253 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

... reallocating p[] to 1 bytes

33 0 0 0 0 0 0 0 *o=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 0 0 0 0 

33 0 0 0 0 0 0 0 *q=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

49 0 0 0 0 0 0 0 *p=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 253 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

... freeing p

33 0 0 0 0 0 0 0 *o=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 0 0 0 0 

33 0 0 0 0 0 0 0 *q=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

49 0 0 0 0 0 0 0 *p=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 253 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

... freeing q

33 0 0 0 0 0 0 0 *o=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33 0 0 0 0 0 0 0 112 210 6 212 50 86 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 0 0 0 0 

33 0 0 0 0 0 0 0 *q=112 210 6 212 50 86 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

49 0 0 0 0 0 0 0 *p=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 253 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

... freeing old p

33 0 0 0 0 0 0 0 *o=144 210 6 212 50 86 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33 0 0 0 0 0 0 0 112 210 6 212 50 86 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 0 0 0 0 

33 0 0 0 0 0 0 0 *q=112 210 6 212 50 86 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

49 0 0 0 0 0 0 0 *p=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 253 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 


Here is the output while compiling with the input '64':


... allocating 64 bytes to p[] (show memory from p[-8] to p[64])

81 0 0 0 0 0 0 0 *p=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

... allocating 64 bytes to q[]

81 0 0 0 0 0 0 0 *p=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

81 0 0 0 0 0 0 0 *q=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

... reallocating p[] to 74 bytes (show old p[], new p[], and q[])

81 0 0 0 0 0 0 0 *o=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

97 0 0 0 0 0 0 0 *p=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

81 0 0 0 0 0 0 0 *q=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

... reallocating p[] to 89 bytes

81 0 0 0 0 0 0 0 *o=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

81 0 0 0 0 0 0 0 *q=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

113 0 0 0 0 0 0 0 *p=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

... reallocating p[] to 64 bytes

81 0 0 0 0 0 0 0 *o=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

81 0 0 0 0 0 0 0 *q=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

81 0 0 0 0 0 0 0 *p=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

... freeing p

81 0 0 0 0 0 0 0 *o=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

81 0 0 0 0 0 0 0 *q=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

81 0 0 0 0 0 0 0 *p=112 210 66 144 174 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

... freeing q

81 0 0 0 0 0 0 0 *o=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

81 0 0 0 0 0 0 0 *q=16 211 66 144 174 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

81 0 0 0 0 0 0 0 *p=112 210 66 144 174 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

... freeing old p

81 0 0 0 0 0 0 0 *o=192 210 66 144 174 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

81 0 0 0 0 0 0 0 *q=16 211 66 144 174 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

81 0 0 0 0 0 0 0 *p=112 210 66 144 174 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 



I did notice how in the memory pointed by q there is a piece of what was pointed by the p one.

What should I focus on while analyzing the output, and most importantly, what do those numbers represent in relation to the definition of malloc, realloc and free?

Thank you in advance for you help.

Xiana
  • 1
  • The first thing you need to know is that the memory allocated by `malloc` is not initialized in any way, its contents is *indeterminate* (and could be seen as random or garbage). The second thing you need to know is that you should never reassign back to the pointer you pass to `realloc`, if `realloc` fails it will return a null pointer but not free the memory pointed to by the first argument (leading to a memory leak as you loose the original pointer). – Some programmer dude May 01 '19 at 11:09
  • Also, all pointers in C are implicitly convertible to `void *`, and `void *` is implicitly convertible to any other pointer. Which is why you [shouldn't cast the result of `malloc` (or it siblings)](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/). – Some programmer dude May 01 '19 at 11:12
  • After the first call to `p = realloc(p, ...);`, `o` is not valid, or points to the same memory as `p`. So you should not call `free(o)`. You have three `free()`, but only two `malloc()`. – HAL9000 May 01 '19 at 15:34

1 Answers1

0

malloc might allocate more than the n bytes required. It has to do some book-keeping so that e.g. free knows how big the block was in order to fully deallocate it.

It's implementation-specific how malloc does that, either it can prepend each block by some known structure that free,realloc can read like here or it can keep some kind of searchable structure with block information. This is subject to heavy optimizations so it might get quite complicated, try to search for "memory allocation algorithm" or similar.

Quimby
  • 17,735
  • 4
  • 35
  • 55