在指针指向的地址处创建结构

时间:2013-03-23 22:17:22

标签: c pointers struct

我有一个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

4 个答案:

答案 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)即可建立分配器将管理的大块(通常称为“竞技场”)。你也可以声明一大堆字节。