从读取输出理解C中的malloc()、realloc()和free()

从读取输出理解C中的malloc()、realloc()和free(),c,memory,memory-management,malloc,heap-memory,C,Memory,Memory Management,Malloc,Heap Memory,我需要写一个关于如何实现内存管理的赋值,以便理解此代码输出中的几个非零数字代表什么 我知道malloc()函数保留指定字节数的内存块。并且,它返回一个void类型的指针,该指针可以转换为任何形式的指针。我还知道,如果动态分配的内存不足或超过要求,可以使用realloc()函数更改以前分配的内存大小 以下是我必须分析的代码: #include <stdlib.h> #include <stdio.h> /*** Just playing with the malloc()

我需要写一个关于如何实现内存管理的赋值,以便理解此代码输出中的几个非零数字代表什么

我知道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;

}
以下是使用输入“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所指的记忆中,有一块p所指的东西

在分析输出时,我应该关注什么,最重要的是,这些数字在malloc、realloc和free的定义中代表什么


提前感谢您的帮助。

malloc
可能会分配超过所需的n字节。它必须做一些簿记,以便(例如,
free
知道区块有多大才能完全解除分配


它是具体实现的,
malloc
如何做到这一点,或者它可以通过一些已知的结构来预处理每个块,而
free,realloc
可以像这里这样读取,或者它可以使用块信息保留某种可搜索的结构。这需要进行大量优化,因此可能会变得非常复杂,请尝试搜索“内存分配算法”或类似的算法。

您需要知道的第一件事是,
malloc
分配的内存没有以任何方式初始化,其内容不确定(可能被视为随机或垃圾)。您需要知道的第二件事是,永远不要重新分配回传递给
realloc
的指针,如果
realloc
失败,它将返回一个空指针,但不会释放第一个参数指向的内存(在松开原始指针时导致内存泄漏),C中的所有指针都可以隐式转换为
void*
,而
void*
可以隐式转换为任何其他指针。这就是为什么在第一次调用
p=realloc(p,…)之后
o
无效,或指向与
p
相同的内存。因此,您不应该调用
free(o)
。您有三个
free()
,但只有两个
malloc()

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