Creating a struct at address pointed by pointer
我有一个
这是typedef的声明
1 2 3 4 5 6 | typedef struct { struct block *next; struct block *prev; int size; unsigned char *buffer; } block; |
我的工作涉及实现malloc,所以我不能使用malloc。 一个块是free_list的一部分,该列表包含我程序堆中所有的空闲内存块。 因此,指向上一个和下一个空闲内存块的上一个和下一个指针。
标题指向free_list的开头。 当我必须拆分时,说第一块空闲内存来满足需要较少空间的malloc()请求,然后该空闲块需要我移动头部并在那里创建一个新的块结构。
希望这是有道理的。 如果没有,任务看起来像这样
您的结构体没有标签,因此您需要给它一个标签,使其指向自身:
1 2 3 4 5 6 | typedef struct block { struct block *next; struct block *prev; int size; unsigned char *buffer; } block; |
如果使用的是C99,则可以根据需要直接在
1 | *(block *)head = (block){NULL, NULL, 0, NULL}; |
现在,只要正确地进行了铸造,您在地址
例如
1 | ((block *)head)->size = 5; |
或者,您为其分配强制转换指针:
1 2 | block *p = (block *)head; p->size = 5; |
操作系统将提供一个API调用来分配您的
您的记录似乎正在执行免费列表。那么,当您还没有分配器时,如何分配列表节点呢?通常的解决方案是在空闲块本身中执行此操作。因此,自由块具有以下结构:
1 2 3 4 5 | typedef struct free_block { struct free_block *next, *prev; size_t size; unsigned char buffer[1]; } FREE_BLOCK; |
现在,此数据结构实际上位于空闲块的开头。它的缓冲区在声明中只有1个字节,但是实际缓冲区是
1 2 3 | static FREE_BLOCK *free_list = sbrk(ARENA_SIZE); free_list->next = free_list->prev = free_list; free_list->size = ARENA_SIZE - offsetof(FREEBLOCK, buffer); |
这会将整个竞技场作为一个单独的块放置在空闲列表中。您的分配器将搜索
简单的自由列表分配器在选择自由块分配方式方面有所不同:首次拟合,旋转优先拟合,最佳拟合,最差拟合等。实际上,旋转优先拟合似乎比其他任何一个都更好或更有效。
顺便说一句,用空闲列表实现的所有常见算法都不需要双重链接。单身的会做。
由于这是一项学术任务,因此只需调用
来自评论:
head points to the start of a place in memory where I can overwrite data...You may assume that I have enough space!
然后获得正确键入的指针:
1 | struct block *p = (struct block *)head; |
并获得该块的副本:
1 | struct block b = *(struct block *)head; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | unsigned char* head = /* whatever you have assuming that it has a sufficient size. */; /* Create a block in memory */ block* b = (block*)malloc(sizeof(block)); /* * modify data in b here as you wish. */ b->next = 0; b->prev = 0; /* etc... */ /* copy b to head */ memcpy(head, b, sizeof(block)); /* free block */ free(b); |
上面假设head有足够的空间来存储一个block实例。
它的作用是创建一个块,然后将内存复制到磁头的位置,然后释放分配的块。