std::string源码探秘和性能分析

本文深入探讨了C++标准库中std::string的内部实现,包括其内存布局、对象大小、copy-on-write机制及其潜在问题。通过对源码的分析,揭示了std::string如何通过引用计数减少不必要的内存拷贝,以及在特定情况下可能面临的性能挑战。此外,还讨论了不同编译器版本中std::string实现的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

std::string源码探秘和性能分析

本文主要讲c++标准库的string的内部实现,以及对象拷贝的性能分析。

文中采用的源码版本为gcc-4.9,测试环境为centos7, x86_64,涉及到指针等数据类型的大小也假定是在64环境位下。

stl源码可以在gnu gcc的官方网站下载到:https://gcc.gnu.org/

头文件

vector头文件,该文件也可以直接在安装了g++的linux系统中找到。主要包含以下头内容:

// vector
#include <bits/stringfwd.h>
#include <bits/basic_string.h>
#include <bits/basic_string.tcc> 
...

很奇怪,里面除了头文件,没有其他内容。我们都知道string是basic_string的一个实例化类,但在这里却没有看到它的定义,于是打开stringfwd.h,果然在这里定义了:

typedef basic_string<char> string;

basic_string.h文件定义了basic_string模板类;

basic_string.tcc存放了一些模板类的成员的实现。c++里面模板的实现不能放在.cpp文件中,必须写在头文件中,如果模板函数实现较复杂,就会导致头文件臃肿和杂乱,这里可以看到stl里面方法,就是把较复杂的实现放在.tcc文件里面,然后当做头文件来包含,我们在写模板代码的时候也可以以此为参考。

内存布局

打开basic_string.h,首先可以看到很多英文注释,大致介绍了一下basic_string的特点和优势,其中有一段是这样的:

   *  A string looks like this:
   *
   *  @code
   *                                     [_Rep]
   *                                     _M_length
   *  [basic_string<char_type>]          _M_capacity
   *  _M_dataplus                        _M_refcount
   *  _M_p ---------------->             unnamed array of char_type
   *  @endcode

这里其实是介绍了basic_string的内存布局,从起始地址出开始,_M_length表示字符串的长度、_M_capacity是最大容量、_M_refcount是引用计数,_M_p指向实际的数据。值得注意的是引用计数,说明该版本的string实现采用了copy-on-write的方式来减少无意义的内存拷贝,后面还会介绍。整体内存布局如下:

这里写图片描述

根据上图推测,一个空string,没有数据,内部开辟的内存应该是8*3=24字节,而sizeof(string)的值似乎为8*4=32字节,因为需要存储四个变量的值。而实际上并不是这样。

string对象的大小

c++对象的大小(sizeof)由非静态成员变量决定,静态成员变量和成员函数不算在内(对此有怀疑的自己可以写代码测试,在这里不过多解释)。通读basic_string.h,非静态成员变量只有一个:

mutable _Alloc_hider  _M_dataplus;

_Alloc_hider是个结构体类型,其定义如下:

struct _Alloc_hider : _Alloc
{
    _CharT* _M_p; // The actual data.
};

_Alloc是分配器,没有成员变量(源码请自行查看,在此不再列出),其对象大

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值