我有一个unsigned char* head
指向内存中的某个addess,现在我必须创建一个我声明从该指针位置开始声明的typedef结构...我很困惑如何那样做!
这是typedef的声明
typedef struct {
struct block *next;
struct block *prev;
int size;
unsigned char *buffer;
} block;
我的任务涉及实现malloc,所以我不能使用malloc。块是free_list的一部分,其中包含我在程序堆中的所有可用内存块块。因此,前一个和下一个指针指向前一个和下一个空闲的内存块。
主管指向free_list的开头。当我必须拆分说第一块空闲内存以满足需要更少空间的malloc()请求时,我需要移动我的头并在那里创建一个新的块结构。
希望这是有道理的。如果没有,则分配看起来像this
答案 0 :(得分:1)
你的struct没有标记,所以你需要给它一个,以便它指向它自己:
typedef struct block {
struct block *next;
struct block *prev;
int size;
unsigned char *buffer;
} block;
如果你正在使用C99,你可以根据需要直接在head
初始化内存,而无需声明临时struct block
:
*(block *)head = (block){NULL, NULL, 0, NULL};
您现在在地址struct block
处拥有head
,只要您正确投放它。
e.g。
((block *)head)->size = 5;
或者为它指定一个演员指针:
block *p = (block *)head;
p->size = 5;
答案 1 :(得分:0)
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有足够的空间来存储块的实例。 它的作用是创建一个块,并将内存复制到head的位置,然后释放已分配的块。
答案 2 :(得分:0)
来自评论:
head
指向内存中可以覆盖数据的地方的开头......你可以假设我有足够的空间!
然后获取正确类型的指针:
struct block *p = (struct block *)head;
并拥有该块的副本:
struct block b = *(struct block *)head;
答案 3 :(得分:0)
操作系统将提供API调用以分配您的malloc
可以分割并提供给呼叫者的内存块。在Linux / unix中查看sbrk
。在Windows中查看Win32堆API。您的记录将指向此块。确保块中没有两个已分配的部分重叠是分配器代码的工作。
看起来您的记录正在实施免费列表。那么当你还没有分配器时,你将如何分配列表节点呢?通常的解决方案是在自由块本身中进行。所以一个空闲块具有以下结构:
typedef struct free_block {
struct free_block *next, *prev;
size_t size;
unsigned char buffer[1];
} FREE_BLOCK;
现在这个数据结构实际上位于空闲块的开头。它的缓冲区在声明中只有1个字节,但实际缓冲区为size
个字节。最初你有类似的东西:
static FREE_BLOCK *free_list = sbrk(ARENA_SIZE);
free_list->next = free_list->prev = free_list;
free_list->size = ARENA_SIZE - offsetof(FREEBLOCK, buffer);
这将整个竞技场作为单个区块放在空闲列表中。您的分配器将搜索free_list
以找到足够大的块,分割出所需的块,将剩余的小块(如果有的话)放回到空闲列表中。对于释放,它会将释放的块添加到列表中并合并相邻的块。
简单的自由列表分配器在如何选择要分配的空闲块方面有所不同:首先适合,旋转第一适合,最佳适合,最差适合等。在实践中,旋转第一适合似乎与任何一个一样好或更好其他人。
顺便提一下,所有使用免费列表实现的常用算法都不需要双链接。单身即可。
由于这是一项学术任务,因此只需调用malloc
(而不是操作系统API)即可建立分配器将管理的大块(通常称为“竞技场”)。你也可以声明一大堆字节。