zoukankan      html  css  js  c++  java
  • C++ 头文件系列(string)----分析string初始化内存模型

    测大小

    这里我们比较4种版本的basic_string模版类,分别是:string, wstring, u16string, u32string. 虽然他们是不同的字符串类型,但是其sizeof的结果却一样,都为40字节(x64下):

    sizeof-image

    看源码

    我们都知道,上面4个不同的类型是同一份模版(basic_string)的实例化,因此它们的内存模型都是相同的。 这里我们来追踪一下string类型的源代码,源码引用VS2013版的标准string库。

    看继承

    看得出,basic_string的继承体系非常复杂(当前无关部分我用...代替了)。

    1. typedef basic_string<char, char_traits<char>, allocator<char> >
    	string;
    				↓↓↓
    2. class basic_string
    	: public _String_alloc<!is_empty<_Alloc>::value,
    		_String_base_types<_Elem, _Alloc> > {...}
    				↓↓↓
    3. class _String_alloc
    	: public _String_val<typename _Alloc_types::_Val_types> {...}
    				↓↓↓
    4. class _String_val
    	: public _Container_base {...}
    				↓↓↓
    5. typedef _Container_base12 _Container_base;
    				↓↓↓
    6. struct _Container_base12 {...}
    

    看成员

    光有继承体系还不够,我们还得看看类成员。 注意,这里不需要关心模版参数,至于为什么,你们自己好好想想喽 >-<)

    members-image

    看定义

    能够看到,_Container_base12类只包含一个指针(指向一个代理类,这里我们不深究),大小永远为1个字长。 因此,我们主要来看看_String_val类的成员定义:

    1. enum
    	 {	// length of internal buffer, [1, 16]
    	  _BUF_SIZE = 16 / sizeof (value_type) < 1 ? 1
    		 : 16 / sizeof (value_type)};
    
      union _Bxty
    	{	// storage for small buffer or pointer to larger one
    	value_type _Buf[_BUF_SIZE];
    	pointer _Ptr;
    	char _Alias[_BUF_SIZE];	// to permit aliasing
    	} _Bx;
    
    2. size_type _Mysize;	// current length of string
    3. size_type _Myres;	// current storage reserved for string
    

    其中,_BUF_SIZE定义了缓冲区的长度:

    • 若value_type类型小于1字节,则 _BUF_SIZE = 16
    • 否则,_BUF_SIZE = 16 / sizeof(value_type)。(留心,这里是整除取商!!!)

    析类型

    这里有几个类型定义非常重要:value_type, pointer, size_type。 从源代码上看,这些类型经过了一层又一层的typedef,源头难辨。 因此,我们转而从标准草案来先解读value_type

    typedef typename traits::char_type		value_type;
    
    X::char_type	->		charT
    charT			->		char
    

    其它两个类型也依理分析,最后得出它们的实际类型分别为:

    types-image

    得结果

    综上,字符串类型内存模型如下:

    memory-model-image

    最后让我们拿string类型来验证一下(><良心保证,下图为代码运行结果,非纯数字打印):

    check-image

  • 相关阅读:
    9.12 其他样式;JS
    9.11 样式表
    9.9 样式表
    PHP延迟几秒后执行,PHP延迟执行,PHP停顿几毫秒后执行 usleep() 和 sleep()
    PHP 去除url参数中出现+、空格、=、%、&、#等字符的解决办法, PHP去除影响url路径的字符
    java第一堂课-常用的电脑快捷键操作和重要的dos命令
    常用第三方接口,支付宝支付,微信支付,软著,IOS开发者账号
    苹果开发者账号申请流程完整版 https://www.jianshu.com/p/655380201685
    thinkphp 去重查询
    将数据导【入】【excel表】格式 前端页面
  • 原文地址:https://www.cnblogs.com/lgxZJ/p/6602518.html
Copyright © 2011-2022 走看看