c - 为什么使用显式空闲列表的分配器需要初始堆大小为 48 字节?

标签 c

我正在考虑使用显式空闲列表实现分配器,并想知道为什么很多人实现 48 字节作为初始大小。

但大多数人使用 48 而不是 24

#define PACK(size, alloc)  ((size) | (alloc))
#define PUT(p, val)  (*(size_t *)(p) = (val))  
#define WSIZE       4     
#define DSIZE       8  
#define CHUNKSIZE  (1<<12)
#define OVERHEAD 24 


static char *heap_listp;  /* pointer to first block */  
static char *mem_brk; /* pointer to last byte of heap plus 1 */

void *mem_sbrk(int incr){
    char *old_brk = mem_brk;

    mem_brk +=incr;
    return (void *)old_brk;
}


int mm_init(void)
{
    if((heap_listp = mem_sbrk(48) == NULL){                                      //Return error if unable to get heap space
        return -1;
    }

    PUT(heap_listp, 0);                                                                  
//Put the Padding at the start of heap
    PUT(heap_listp + WSIZE, PACK(OVERHEAD, 1));                                             
//Put the header block of the prologue
    PUT(heap_listp + DSIZE, 0);                                                             
//Put the previous pointer
    PUT(heap_listp + DSIZE + WSIZE, 0);                                                     
//Put the next pointer
    PUT(heap_listp + OVERHEAD, PACK(OVERHEAD, 1));                                          
//Put the footer block of the prologue
    PUT(heap_listp + WSIZE + OVERHEAD, PACK(0, 1));                                         
//Put the header block of the epilogue


    if(extend_heap(CHUNKSIZE / WSIZE) == NULL){                                             //Return error if unable to extend heap space
        return -1;
    }

    return 0;
}

我认为我们有 6 个单词(填充、序言标题 block 、序言页脚 block 、前一个指针、下一个指针和尾声标题 block ) 所以我认为我们需要这样声明

if((heap_listp = mem_sbrk(24)) == NULL)

请随时指出我遗漏的内容。

最佳答案

    PUT(heap_listp, 0); //ofset 0                                                                  
    PUT(heap_listp + WSIZE, PACK(OVERHEAD, 1));    //offset 4 - appears to contain a length (of OVERHEAD bytes)
    PUT(heap_listp + DSIZE, 0);           //offset 8                                                  
    PUT(heap_listp + DSIZE + WSIZE, 0);  //offset 8 + 4 = 12                                                   
    PUT(heap_listp + OVERHEAD, PACK(OVERHEAD, 1)); // offset 24 - another length of OVERHEAD bytes                                   
    PUT(heap_listp + WSIZE + OVERHEAD, PACK(0, 1)); //offset 24 + 4

显然,当您写入字节 31 时,sbrk 需要大于 24

所以看起来初始设置由 2 个 block 组成,两个 block 都是 OVERHEAD 字节长。

对 sbrk 使用 2 * OVERHEAD 会更清楚。使用结构体作为内存区域头也是如此。

关于c - 为什么使用显式空闲列表的分配器需要初始堆大小为 48 字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56273178/

相关文章:

c++ - OpenCV 程序运行时错误

c - 为什么我在调用 realloc() 后得到模运算的浮点异常?

c - 用 C 中的数字对填充数组

c++ - 按位运算符计算校验和

c - 在不编译和执行代码的情况下找到类型大小的最简单方法是什么?

c - 函数指针和函数由于参数不兼容

c++ - 下面的代码是否真的释放了 C/C++ 中的内存?

c - 从文本文件中读取十六进制并将其拆分为C程序

c++ - Coverity 扫描设置?

c - 在C中,我如何获取符号链接(symbolic link)的路径(我的意思是符号链接(symbolic link)的路径而不是目标的路径)?