string類是C++中專門處理字符串的類,它的實際上是basic_string<char>的一個typedef。它有四個跌代器:
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef _String_iterator<_Elem, _Traits, _Alloc> iterator;//models random iterator
typedef _String_const_iterator<_Elem, _Traits, _Alloc> const_iterator;////models random iterator//models random iterator
一個靜態常量:static const size_typed npos = -1;
basic_string模板定義的類型:
typedef traits traits_type; //某個具體類型的模板參數
typedef typename traits::char_type value_type;
typedef Allocator allocator_type;
typedef typename Allocator::size_type size_type;
typedef typename Allocator::difference_type difference_type;
typedef typename Allocator::reference reference;
typedef typename Allocator::const_reference const_reference;
typedef typename Allocator::pointer pointer;
typedef typename Allocator::const_pointer const_pointer;
針對不同的廠商的實現是不同的。
memset可以用與string類嗎?有網友提出以下問題:
1 void fun()
2 {
3 string temp;
4 char buff[] = "123456789";
5 while(true)
6 {
7
8 memset(&temp, '\0', sizeof(string));
9 temp = buff;
10 }
11 }
上面的代碼安全性如何?一直想寫篇文章表述一下這個問題,談談自己的看法。最近在項目大量的用到STL,出現了不少問題,上面的問題就是其中之一,上面的代碼肯定不安全。while循環只是放大一下執行效果。
在VC的string的實現上,有個uion _bxty
{ // storage for small buffer or pointer to larger one
_elem _buf[_buf_size];
_elem *_ptr;
} _bx;
而_buf_size值為:
enum
{ // length of internal buffer, [1, 16]
_buf_size = 16 / sizeof (_elem) <1 ? 1
: 16 / sizeof(_elem)};
在模板參數_elem為char時, _buf_size為16, 而union _bx里保存的是一個字符串指針或一個字符緩沖大小, 當字符串長度小于等于15(別忘了字符串還有個0結尾的字符)不必額外分配內存而是直接使用string對象本身已經分配的內存, 否則使用allocator來分配一塊新的內存以保存字符串. 而string不帶任何參數的構造函數調用了_tidy函數, 在這個函數中會設置string的成員變量_myres(預留空間大小)為15(_buf_size-1), 如果將memset用于string,memset就會于破壞其內部變量_myres的值, 導致在之后對string對象進行操作時, 即時字符串大小不大于15也會引發內存分配的動作, 而這實際上是不應該發生的(應該直接使用string本身的內存而不是新申請內存塊), 于是就有了在字符串大小小于16字節時, 分配的內存沒有釋放的結果. 這樣做的結果是會導致內存泄露。