一、新版c++11版红黑树类图
最近在研究《STL源码剖析》,发现书中的红黑树是旧版G2.9编译器的,在linux平台上(ubundun22.04.1)测试了一下sizeof(map)和sizeof(set),发现都是48字节(64位系统),不符合STL上的红黑树,在网上找了一下没找到最新版本的解释,解释不出来为什么是48字节,于是下载了linux上c++11的/usr/include/c++/11源码,自己看里面的数据成员
以下的类图只画了数据成员,用于研究字节大小,没有画里面的成员函数

看图可以发现最上面的_Rb_tree_node_base里面有4个数据成员,通过继续看源码(如下),可以知道color就是enum枚举类型(大小为4个字节),用于确定结点颜色是红色还是黑色,_Base_ptr是指针,指向本身这个类型(指针类型64位系统大小为8个字节),由于内存对齐,这个类型的对象(这个结构体)的大小为4+8*3 = 28-->32(内存对齐)
// 只贴了源码的前半
struct _Rb_tree_node_base
{
typedef _Rb_tree_node_base* _Base_ptr;
typedef const _Rb_tree_node_base* _Const_Base_ptr;
_Rb_tree_color _M_color;
_Base_ptr _M_parent;
_Base_ptr _M_left;
_Base_ptr _M_right;
};
enum _Rb_tree_color
{ _S_red = false,
_S_black = true
};
而头结点除了有这个类型的对象还有一个数据成员_M_node_cont是size_t类型(4字节),但是由于有一个结构体类型的对象_M_header,和这个对象进行内存对齐,导致32+4 = 36-->40,所以_Rb_tree_header的大小(sizeof)是40字节
而_Rb_tree_impl还有一个成员对象,是比较器,比较器本身并没有数据成员,但是它的对象作为另一个类的成员后需要占位1个字节,而由于内存对齐,最终应该为40+1 = 41-->48字节
以上就是64位系统map和set都是48字节的解释(上述的内存测试已经自己写过代码测试无误)

二、旧版红黑树(STL)
旧版中一共有三个数据成员,Rb_tree_alloc_base中有一个指针类型的数据成员(指向节点),_Rb_tree_base继承了这个类,_Rb_tree继承了_Rb_tree_base类并且添加了size_t类型和比较器的两个数据成员,所以一共是4+4+1=9-->12字节(内存对齐)(32位系统)
177万+

被折叠的 条评论
为什么被折叠?



