SGISTL 里面用到 union 来管理内存链表

《STL源码剖析》里面关于 STL allocator 的二级配置器,也就是使用空闲空间链表来存储各个size(均为 8Bytes 倍数)的 chunk。
其中有用到一个 union 来表示每个 chunk:

union obj{  
    union obj * free_list_link;  
    char client_data[1]; /* The client sees this.*/  
};  

侯捷对此结构的解释为:

由于union之故,从其第一字段观之,obj可被视为一个指针,指向相同形式的另一个obj。从其第二字段观之,obj可被视为一个指针,指向实际区块。

其中为什么会用 union 来表示,以及 client_data 字段的作用,其实很简单:
假如有一个 obj chunk 被分配给用户,例如如下:

obj *objptr;

client_data没有实际用到,你可以认为它是一种 coding 技巧,比如如果用户需要一个 char* 类型的缓存或内存空间,可以直接调用第一句,而不需要第二句这种强制类型转换。

char *buffer = objptr->client_data;
char *buffer = (char*)objptr;

并且这里用到了一个rule,那就是当这个 obj chunk 在 freelist 内时,说明它的空间是空闲的,因此此时用强制类型转换可以在其中构造出来一个 obj 对象来,其中 free_list_link 来存储下一个 chunk 节点。而当它被分配给用户时,用户可以覆盖掉这个内存。所以这就是为什么第二层分配器在调用 deallocate 时需要一个 size_t n 参数,因为它需要定位到返回的 chunk 具体的 freelist 链表。

知乎有对这个问题的讨论,但是两个赞数最高的答案扯到编译期优化上,真是晕了。
找到有博客也提到这个问题了: http://blog.csdn.net/laojiu_/article/details/77601205

posted on 2018-03-19 21:06  daghlny  阅读(365)  评论(0编辑  收藏  举报

导航