STL源碼分析--string

更多精彩內容,請關注微信公衆號:後端技術小屋c++

1 string的數據結構

從定義可知, string實際上是base_string的特化類,string使用默認的內存分配器__STL_DEFAULT_ALLOCATOR(_CharT)後端

template <class _CharT, 
          class _Traits = char_traits<_CharT>, 
          class _Alloc = __STL_DEFAULT_ALLOCATOR(_CharT) >
class basic_string;


typedef basic_string<char>    string;

traits是c++中一個重要特性,使用traits可在編譯器肯定類型相關的信息。好比某個模板參數是否爲整形。string中默認的模板參數_Traitschar_traits<_CharT>, 定義以下api

template <class _CharT> class char_traits
  : public __char_traits_base<_CharT, _CharT>
{}

能夠看到char_traits<_CharT>繼承自__char_traits_base<_CharT, _CharT>,其中定義了字符類型_CharT的各類操做,供basic_string方法調用:例如basic_string::operator=中調用了__char_traits_base::lengthbasic_string::clear中調用了__char_traits_base::assign數組

如下是一些常見的字符操做微信

  • assign: 複製字符值
  • eq: 相等
  • lt: 小於
  • compare: 比較(小於返回-1, 等於返回0, 大於返回1)
  • length: 字符數組的長度(需以null char值結尾)
  • find: 尋找某個字符值
  • move: 調用memmove複製字符數組A到B
  • copy: 調用memcpy複製字符數組A到B(memmovememcpy做用類似,都用於字節數組的複製,可是後者不容許內存區域有重疊)
  • eof: 字符值是否等於-1
static void assign(char_type& __c1, const char_type& __c2) { __c1 = __c2; }
  static bool eq(const _CharT& __c1, const _CharT& __c2) 
    { return __c1 == __c2; }
  static bool lt(const _CharT& __c1, const _CharT& __c2) 
    { return __c1 < __c2; }

string的內存結構相似於vector,由一段連續的內存緩衝區組成,_M_start爲已用緩衝區的首地址,_M_finish爲已用緩衝區的尾地址,_M_end_of_storage爲空閒緩衝區的尾地址, 以下圖所示數據結構

string的數據結構

2 string的API

由於string的API和vector相似,所以方法也相似, 此處略過源碼分析

3 string使用時的注意事項

  1. 執行clear時,string佔用的內存並不會釋放,只是_M_finish = _M_start而已。所以若是須要釋放string內存,可執行`str.swap(string())``
  2. 執行reserve(len)時,會從新分配1+max(size()+len)大小的內存緩衝區, 並將舊緩衝區數據複製到新緩衝區,開銷比較大。所以不要隨便執行reserve,以避免內存的從新分配複製。當肯定某個對象的最大長度時,可以使用reserve預分配足夠大的內存,可避免後續字符串增加致使內存的從新分配複製。

推薦閱讀code

更多精彩內容,請掃碼關注微信公衆號:後端技術小屋。若是以爲文章對你有幫助的話,請多多分享、轉發、在看。
二維碼對象

相關文章
相關標籤/搜索