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字节时, 分配的内存没有释放的结果. 这样做的结果是会导致内存泄露。