Benjamin

静以修身,俭以养德,非澹薄无以明志,非宁静无以致远。
随笔 - 279, 文章 - 0, 评论 - 196, 引用 - 0
数据加载中……

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

posted on 2009-05-16 23:24 Benjamin 阅读(2103) 评论(0)  编辑 收藏 引用 所属分类: 泛型编程


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理