首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > VSTS >

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

2012-12-17 
DEBUG下,VS 2010的vector和相关迭代器的安全检查和记录功能 本文分析DEBUG配置下,VS 2010中std::vector和

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

 

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

 

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

DEBUG上,VS 2010的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 */

                }

 

 


热点排行