memset(string) 是错误

来源:互联网 发布:淘宝仓库招聘 编辑:程序博客网 时间:2024/06/10 15:47
string和memset
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字节时, 分配的内存没有释放的结果. 这样做的结果是会导致内存泄露。



from:  http://www.cppblog.com/zhangyq/archive/2009/05/16/83154.html

0 0
原创粉丝点击