Понимание malloc (), realloc () и free () в C из чтения вывода - PullRequest
0 голосов
/ 01 мая 2019

Мне нужно написать назначение относительно того, как реализовано управление памятью, чтобы понять, что представляют собой несколько ненулевых чисел в выходных данных этого кода.

Я знаю, что функция malloc () резервирует блок памяти с указанным количеством байтов. И он возвращает указатель типа void, который может быть преобразован в указатель любой формы. Я также знаю, что если динамически выделенной памяти недостаточно или больше, чем требуется, вы можете изменить размер ранее выделенной памяти с помощью функции realloc ().

Вот код, который я должен проанализировать:

#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;

}

А вот вывод, компилирующий файл без каких-либо других входных данных:


... 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 


Вот вывод при компиляции с помощью ввода '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 



Я заметил, что в памяти, на которую указывает q, есть фрагмент того, на что указывает р.

На что мне следует обратить внимание при анализе выходных данных и, что наиболее важно, что эти числа представляют в отношении определения malloc, realloc и free?

Заранее благодарю за помощь.

1 Ответ

0 голосов
/ 01 мая 2019

malloc может выделить больше, чем требуется n байтов. Он должен вести бухгалтерию, например, free знает, насколько большим был блок, чтобы полностью освободить его.

Это зависит от реализации, как malloc делает это, либо он может добавлять к каждому блоку некоторую известную структуру, которую free,realloc может читать как здесь, либо он может сохранять какую-то структуру с возможностью поиска с информацией о блоке. Это требует тщательной оптимизации, поэтому может оказаться довольно сложным, попробуйте поискать «алгоритм выделения памяти» или аналогичный.

...