如何使用指针将结构写入一块内存

J F*_*ird 0 c malloc struct pointers memory-management

我正在使用空闲列表实现内存管理器,其节点是一个结构,包含有关要管理的内存块的元数据.

我会在一开始就调用malloc()一次从操作系统中获取一块内存.然后我将使用我自己的程序管理它.在后续程序中,我不能再使用malloc(),所以我必须将元数据(节点列表)保存在该内存中.这是我的问题,假设:

struct list *node1 = malloc(n_bytes);   // only call malloc() once here
node1->memStart = node1 + sizeof(struct list)   // beginning address of managable
                                                // memory
node1->size = bytes_allocated;
node1->used = 1;
node1->next = NULL;
// starting address of node2
struct list *node2 = node1->memStart + node1->size;      // used another node to track the second piece of
                                                        // that memory
node2->size = 4096; 
node2->used = 0;      // node2's memory is unused yet
node2->memStart = node2 + sizeof(struct list);
node2->next = NULL;
node1-next = node2;   // link them
Run Code Online (Sandbox Code Playgroud)

所以在这里我不确定我是否已经将这些元数据(size,used,memStart,next)写入从node1开始的内存地址,从而使它看起来像:

----------<----node1
|  size  |
----------
|  used  |
----------
|memStart|------|
----------      |
|  next  |      |
----------      |
|        |<-----|
|  mem   | 
|        |
----------<----node2
|  size  |
----------
|  used  |
----------
|memStart|
----------
|  next  |
----------
|        |
|  mem   | 
|        |
----------
Run Code Online (Sandbox Code Playgroud)

所以我只是想知道上面的代码后,内存布局是否会像上面绘制的那样.它主要是关于node2,我不确定我是否可以像这样使用它来将元数据写入内存.这很重要,因为随着越来越多的内存被分配,我需要更多的节点来跟踪它们.我认为没有malloc这样做的方法(否则编写我自己的经理没有意义)就是做指针算术来将内存切成块并使用开销来跟踪它们.

列表的结构应该是:

struct list{
  int size;
  void *memStart;
  int used;
  struct list *next;
}
Run Code Online (Sandbox Code Playgroud)

Fil*_*ves 6

不,内存布局不会像上面绘制的那样.考虑这一行:

node1->memStart = node1 + sizeof(struct list)
Run Code Online (Sandbox Code Playgroud)

由于指针运算的,node1 + x将按比例x通过sizeof(*node1).也就是说,node1 + sizeof(struct list)产生指向node1 + sizeof(struct list)*sizeof(struct list)字节之外的地址的指针.这是C中的基本指针算法.你想要这样:

node1->memStart = ((char *) node1) + sizeof(struct list)
Run Code Online (Sandbox Code Playgroud)

根据memStartin 的定义struct list,这可能也是错误的:

struct list *node2 = node1->memStart + node1->size;
Run Code Online (Sandbox Code Playgroud)

不过,如果你申报memStartchar *,它应该工作,假设bytes_allocated(你不告诉你如何得到它)是正确的.

此行与等效的行具有相同的错误node1:

node2->memStart = node2 + sizeof(struct list);
Run Code Online (Sandbox Code Playgroud)