DEBUG下,VS 2010的vector和相关迭代器的安全检查和记录功能

 

本文分析DEBUG配置下,VS 2010中std::vector和相关迭代器提供的安全检查和记录功能。有的功能非常耗时。幸好在RELEASE配置下,这些功能都被预编译指令去掉了。当然这也说明,针对VC程序的效率测试必须采用RELEASE版本,否则测试结果很难说明问题。

 

std::vector和std::vector迭代器的类图



其中,_Vector_iterator<_Myvec>是std::vector<_Ty,_Alloc>::begin()返回的类型,

_Vector_const_iterator<_Myvec>是相应的const iterator

迭代器的有效性检查

在DEBUG配置下,_Vector_const_iterator负责检查迭代器的有效性:

  •  在迭代器递增、递减、解引用等操作的时候,检查迭代器是否在vector的合法范围内。
  •  两个迭代器比较大小的时候,验证它们迭代器是同一个vector的迭代器。

比如以下取值函数,就是检查指针是否越界。

reference operator*() const

                {       // return designated object

 #if _ITERATOR_DEBUG_LEVEL == 2

                // 这里检查指针没有越界

                if (this->_Getcont() == 0

                        || this->_Ptr == 0

                        || this->_Ptr < ((_Myvec *)this->_Getcont())->_Myfirst

                        || ((_Myvec *)this->_Getcont())->_Mylast <= this->_Ptr)

                        {       // report error

                        _DEBUG_ERROR("vector iterator not dereferencable");

                        _SCL_SECURE_OUT_OF_RANGE;

                        }

 

迭代器的单向链表

std::vector<_Ty,_Alloc>通过基类_Vector_val<_Ty,_Alloc>包含了一个_Container_proxy对象,_Container_proxy::_Myfirstiter指向了一个单向链表P的头指针,P中包含一个vector对象的所有迭代器的指针。因此

  • 新建一个迭代器,需要向P的头部插入一个指针,这是在常数时间完成的。
  • 销毁一个迭代器,需要从P中删除迭代器对应的指针。由于只保存了单向链表P的头指针,这具有线性的时间复杂度(见下面的代码)。如果一个容器的迭代器对象非常多,(比如hash_map的内部实现),则会非常耗时。

// 把迭代器指针从单向列表中删除

        void _Iterator_base12::_Orphan_me()

                {       // cut ties with parent

 #if _ITERATOR_DEBUG_LEVEL == 2

                if (_Myproxy != 0)

                        {       // 从链表的头指针向后遍历,找到当前元素的前一个元素

                        _Iterator_base12 **_Pnext = &_Myproxy->_Myfirstiter;

                        while (*_Pnext != 0 && *_Pnext != this)

                                _Pnext = &(*_Pnext)->_Mynextiter;

 

                        if (*_Pnext == 0)

                                _DEBUG_ERROR("ITERATOR LIST CORRUPTED!");

                        *_Pnext = _Mynextiter;

                        _Myproxy = 0;

                        }

 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

                }

 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值