编写一个自定义malloc,将信息存储在指针中



我最近读到一系列自动内存管理技术,这些技术依赖于在分配器返回的指针中存储信息,即头的几个位,例如区分指针或存储与线程相关的信息(注意,我在这里不是在谈论有限字段引用计数,只是不可变信息)。

我喜欢玩弄这些技巧。现在,为了实现它们,我需要能够从分配器返回具有特定形状的指针。我想我可以使用最小权重的位,但这将需要填充,看起来非常消耗内存,所以我认为我应该使用最重的位。然而,我对如何做到这一点没有好主意。我是否有一种方法,调用mallocmalloc_create_zone或一些相关的函数,并请求一个指针,总是以给定的位开始?

谢谢大家!

实际上可以在指针中存储的信息量是非常有限的(每个指针通常是1或2位)。而且每次对指针解引用的尝试都必须首先屏蔽掉魔术信息。顺便说一句,这种技术通常被称为标记。

 #define TAG_MASK   0x3
 #define CONS_TAG   0x1
 #define STRING_TAG 0x2
 #define NUMBER_TAG 0x3
 typedef uintptr_t value_t; 
 typedef struct cons {
     value_t car;
     value_t cdr;
 } cons_t;
 value_t
 create_cons(value_t t1, value_t t2)
 {
     cons_t* pair = malloc(sizeof(cons_t));
     value_t addr = (value_t)pair;
     pair->car = t1;
     pair->cdr = t2;
     return addr | CONS_TAG;
 }
 value_t
 car_of_cons(value_t v)
 {
     if ((v % TAG_MASK) != CONS_TAG) error("wrong type of argument");
     return ((cons_t*) (v & ~TAG_MASK))->car;
 }

这种技术的一个优点是,可以直接从指针本身推断对象的类型。您不需要对其解引用(例如,为了读取特殊的type字段或类似内容)。许多使用这种方案的语言实现也有一个特殊的标记组合,用于"即时"数字和其他小值,这些值可以直接使用"指针"表示。

缺点是,可以存储的信息量非常有限。此外,正如示例代码所示,您必须注意每次访问对象时的标记,并且需要在实际使用指针之前"取消"它。

根据观察,在大多数平台上,所有指向malloc内存的指针实际上都对齐在非字节边界上(通常为8字节),因此最低有效位始终为零。

相关内容

  • 没有找到相关文章

最新更新