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
上一篇: svn汉化及android studio+svn分支同步主干代码
下一篇: 浏览器与服务器的交换过程