SGI STL中的union obj

这两天开始看侯捷的STL源码剖析,STL的allocator中的第二级配置器__default_alloc_template时,free-list的节点结构:

union obj
{
    union obj* free_list_link;
    char client_data[1];
};

书中对此的解释是是:

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

此处的char client_data[1]不太好理解,尤其是在allocate、refill、mempool中都没有用到这个字段。

个人感觉此处至少涉及了三个知识点:1,链表;2,union的共享内存;3,柔性数组;

加入为此节点申请一个8字节的空间:

obj * block = (obj *) malloc(8);
printf("%x\n", block);
printf("%x\n", block->client_data);

此处,block与block->client_data地址是一样的,从内存上来看,由于union的缘故很好理解:

申请的八个字节,前四个字节可以用来存储一个指针free_list_link用于指向下一个obj内存块,或者头一个字节就是client_data[1],由于数组名即代表指针,那么client_data==block,都指向申请的8字节内存的首地址。

注意:以上特性在同一时刻只能取其一(也就是是否将内存返回给了客户端)

所以好多人说用一个结构体完全是可以实现(有人说已经尝试过注释掉没有问题,不知真假):

struct obj
{
    struct obj* free_list_link;
};

那么为什么作者一定要添加client_data呢?以下是我了解到的两个解释:

1,一种指针类型转换

一般内存buffer我们都是使用char*指针,如果要使用obj的地址,还得加上 (char *)block 进行强制类型转换。反之直接使用myBlock->client_data即可,方便多了。

2,构造包含柔性数组成员的节点,这样一个结构体可以占用任意大小的内存块

由于,二级配置器维护了16个free-list,每个free-list节点所占的内存是不一样的,已8的倍数递增,最大128字节。所以通过包含柔性数组,就可以将一个节点结构通用的满足不同size的结点。

 

以上两点的解释始终不能彻底的解决我心中的疑惑,就感觉实现上面的目的而添加client_data,根本就只是充分而非必要条件:

比如说第一点,用户根本不可能用联合体的成员访问自己申请的内存空间,都是直接使用节点的指针,从书上也能看出来,返回值为result,而result的类型就是obj*

在如第二点:obj*节点指针本身就是可以指向不同size的空间,为啥还非得用柔性数组成员呢?

https://blog.csdn.net/qq973177663/article/details/50815055?locationNum=9

中提到“设计者还是一种对精炼代码的极致追求吧”,如何追求的也不理解。。。

 

嗨,一知半解的往下看真的好难受啊!!!!

 

参考:

观点一:https://blog.csdn.net/w450468524/article/details/51649222

观点二:https://bbs.csdn.net/topics/340252517

柔性数组:

https://blog.csdn.net/vgxpm/article/details/42871601

http://www.cppblog.com/Dream5/articles/148386.html

其他:

https://segmentfault.com/q/1010000006209284/a-1020000006209968

https://bbs.csdn.net/topics/390408109

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值