测大小

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

看源码

我们都知道,上面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 {...}

看成员

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

看定义

能够看到,_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

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

得结果

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

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

C++ 头文件系列(string)----分析string初始化内存模型的更多相关文章

  1. C++ 头文件系列(ios)

    1 简介 我们都知道,平时常用的那些标准流,诸如iostream.ofstream.ifstream等等,其实都是对应的basic_XXX模版的实例类. 而这些basic_XXX类模版又都是继承自同一 ...

  2. C++ 头文件系列(iomanip)

    1. 简介 该头文件定义了一些参数化的操纵器(manipulatators),注意ios头文件也定义了一些. 2. maniapulators 2.1 C++98 resetiosflags : 重置 ...

  3. C++ 头文件系列(array)

    注意,该头文件仅在C++11中标准才开始出现. 简介 与语言内置的数组一样, array类模版支持几乎所有内置数组包含的特性: 顺序的(sequence) 内存连续的(contiguous stora ...

  4. C++ 头文件系列(queue)

    简介 这个头文件定义了两个跟队列有关的类----quque.priority_queue,分别实现的是队列 和 优先队列这两个概念. 但是与这两个类模版与其它类模版(vector.array等)最大的 ...

  5. C++ 头文件系列(stack)

    简介 该头文件只含有一个类模版stack, 它实现栈的概念,是一个容器适配器(说实话,在写这篇随笔之前我都不知道有这么个类模版). 栈 栈只有一个重要的特性: LIFO(last-in first-o ...

  6. C++ 头文件系列(vector)

    简介 vector头文件包含vector的类模版以及该模版的显示特化版本vector< bool >. vector是C++容器库中非常通用的一种容器,如果你不知道该决定使用哪一种容器,或 ...

  7. C++ 头文件系列(map)

    简介 该头文件包含两个概念相似的容器----map.multimap. 而这两个容器反映的概念就是 映射. 这两个容器 相同 的属性有: 关联性 映射 动态增长 键(Key)唯一性 这两个不相同的属性 ...

  8. C++ 头文件系列(unordered_map、unordered_set)

    简介 很明显,这两个头文件分别是map.set头文件对应的unordered版本. 所以它们有一个重要的性质就是: 乱序 如何乱序 这个unorder暗示着,这两个头文件中类的底层实现----Hash ...

  9. C++ 头文件系列(iterator)

    简介 该头文件围绕迭代器展开,定义了一系列与迭代器有关的概念,但最最最重要的一点就是----它和其它容器一起实现了C++容器的Iterator设计模式. Iterators are a general ...

随机推荐

  1. 简学Python第二章__巧学数据结构文件操作

    #cnblogs_post_body h2 { background: linear-gradient(to bottom, #18c0ff 0%,#0c7eff 100%); color: #fff ...

  2. ContextMenu控件引用以及不用v4包的方法

    最近想撸个APP出来玩玩,本想用Yalantis出的SideMenu,结果因为依赖问题放弃了,改用他们家的ContextMenu. 如果你用了v4包 那么问题就比较简单了,直接打开项目中app中的bu ...

  3. IO的构造方法

    package com.file; /* File的构造方法: File(String pathname); File(File parent,String child); File(String p ...

  4. HDU 2520 我是菜鸟,我怕谁

    我是菜鸟,我怕谁 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  5. Java(多态练习 instanceof)

    /* 题目: (多态,instanceof)有如下代码 class Animal { private String name; // 1 } class Dog extends Animal { // ...

  6. 使用光盘iso实现Linux操作系统的自动安装部署

    前边写了一篇使用 PXE 的方式批量安装操作系统,不是任何时候任何地方都有环境来通过 PXE 方式来进行安装.如果此时需要通过光盘安装,默认的情况下是通过交互式方式进行安装,其实也可以通过 kicks ...

  7. click延时300ms的故事

    这要追溯至 2007 年初.苹果公司在发布首款 iPhone 前夕,遇到一个问题:当时的网站都是为大屏幕设备所设计的.于是苹果的工程师们做了一些约定,应对 iPhone 这种小屏幕浏览桌面端站点的问题 ...

  8. 分布式配置管理--百度disconf搭建过程和详细使用

    先说官方文档:http://disconf.readthedocs.io/zh_CN/latest/index.html 不管是否要根据官方文档来搭建disconf,都应该看一下这一份文档.精炼清晰地 ...

  9. JAVA对特殊的字符串进行html编码

    SourceURL:about:blank /** * Created by Administrator on 2016/9/22. */public class HtmlEncode { publi ...

  10. JavaScript 毒瘤和糟粕(需要注意的地方)

    简介 我想这是在我总结JavaScript系列中最为需要注意的,最为重要的内容.你必须要去了解这些问题特性,才能准备好应对措施,这真的很重要. 毒瘤 全局变量 全局变量的存在的确是带来了方便,但是我觉 ...