Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > C/C++ > vc7.1中stl::deque的大bug
【标  题】:vc7.1中stl::deque的大bug
【关键字】:vc7.1,stl,deque,bug
【来  源】:http://blog.csdn.net/wingfiring/archive/2006/01/16/581318.aspx

vc7.1中stl::deque的大bug

Your Ad Here 测试程序员一直报告说我写的程序有内存泄漏,在前几天怀疑了ADO以后,内存泄漏问题仍然没有发现原因。因为相信自己的能力,首先是源代码排查,看自己写的源代码,怎么都没发现有内存泄漏的迹象啊。为什么会内存泄漏呢?奇怪!
  只好先分析一下测试程序员怎么测的:他是在给我做压力测试,首先,是内存狂涨,这是预料之中的:来不及处理的数据会在内存中排队。测试程序跑完了,按照常规,排队数据会逐渐处理掉,内存应该下降才对,因为是多线程协作的程序,仔细查看了自己写的带锁的队列,看不出问题。开始郁闷了,怀疑是不是其他的某个部分有内存泄漏?但是回想自己的代码,几乎从未使用过原始指针,不应该啊,而且,那么大数量的内存泄漏,肯定是在某个压力很大的地方产生的,而各个环节之间,就是通过我的LockedQueue来传递数据的,甚至怀疑是不是push_back的时候分配内存失败导致的了。
  终于,自信心崩溃,怀疑自己的代码确实有bug,只是自己没有看出来,于是,在控制台部分增加对队列大小的监视。当系统其他部分都工作完毕,唯有将某个队列写文件的线程还在忙碌时,发现,尽管队列大小在迅速下降,内存则分毫未动。问题差不多肯定出在我的pop上了。查看pop代码,还是没看出任何问题。突然灵光一闪:我的队列基于std::deque实现的,难道ms的stl::deque的实现有问题?因为,vector pop数据并不减少内存的概念已经深入骨髓了,而deque释放元素后,会释放内存一直是用来和vector作对比的,一直以为,ms的deque在弹出元素时,如果能空闲出一个块时,就一定会把这个块释放掉的(deque是以块的方式分配内存的)。既然怀疑了,先写一个测试程序:
 int count = 1500 * 10000;
    deque<RawUserInfo> t;
    RawUserInfo info;

    for ( int i = 0; i < count; i++)   {
        t.push_back(info);
    }
    while(!t.empty())    {
        t.pop_front();
    }
    cout << "please check mem";
果然,耗掉了我1.5G内存,没有释放!
去看一看源代码吧:
 if (!empty())
            {    // something to erase, do it
            size_type _Block = _Myoff / _DEQUESIZ;
            this->_Alval.destroy(_Map[_Block] + _Myoff % _DEQUESIZ);
            if (_Mapsize * _DEQUESIZ <= ++_Myoff)
                _Myoff = 0;
            if (--_Mysize == 0)
                _Myoff = 0;
            }
只有destory,没有deallocate!郁闷吶,害我这么久,还一直怀疑测试人员的数据。不过也有高兴的一面:俺的代码还是经得起考验的~~。
再接再厉,顺便看看vc8.0的stl,除了增加了一点debug时的支持,问题照旧。再看看俺喜欢的stlport,手头上的是4.6.2版本,有内存释放的代码:
void pop_front() {
    if (this->_M_start._M_cur != this->_M_start._M_last - 1) {
      _STLP_STD::_Destroy(this->_M_start._M_cur);
      ++this->_M_start._M_cur;
    }
    else
      _M_pop_front_aux();
  }
template <class _Tp, class _Alloc >
void
__deque__<_Tp,_Alloc>::_M_pop_front_aux()
{
  _STLP_STD::_Destroy(this->_M_start._M_cur);
  this->_M_map_size.deallocate(this->_M_start._M_first, this->buffer_size());
  this->_M_start._M_set_node(this->_M_start._M_node + 1);
  this->_M_start._M_cur = this->_M_start._M_first;
}
而且,我还发现了一个问题,按照stl其他部分惯例,stl一般是不关心调用条件是否满足的,程序原一定要自己保证的,例如,我们绝不应该在在一个空的容器上:*cont.begin();
因此,我们也不应该在空deque上pop_front();然而,ms的stl却多了个if(!empty()).在一次,可爱的stlport和我预期的一直,并没有检查pop的合法性问题。

这种细节的障碍,真是害死人啊!
再来反省ms的实现:它愿意增加一个empty的检查,却不实现deque的内存缩减,似乎让我看到了一些微软的思维逻辑。
水货笔记本的保修问题:【上一篇】
[原创]判断checkbox是否选中:【下一篇】
【相关文章】
  • 目前发现的VS2005 asp.net 数据绑定bug (二) -关于ObjectDatasource 和TableAdapter
  • C++ STL概述
  • 目前发现的 asp.net数据绑定的几个BUG(不定期连载)
  • [Bug] .NET 2.0 的Bug —— ComboBox中不能添加Component.
  • VC嵌入python时debug版lib下载
  • 将ASP的Debug变得简单的两个函数!
  • 求助-未懂sgi的stl此源码
  • 当VC的Release版与Debug版不一致时
  • 理解STL---understanding stl
  • stl 函数对象
  • 【随机文章】
  • Alexa排名新高-升776位(手机网址之家,www.mobi123.cn)
  • 关于在Eclipse中使用JDK5.0的中文API方法。
  • 为爱你是怎么想的?
  • 代码签名和安全邮件的使用
  • 常见网络安全产品(5)
  • CSDN广告清理器
  • MFC应用集成VBA二次开发
  • Hal Fulton: 我爱 Ruby 的三十七个理由
  • HA5.2安装配置测试完全手册
  • 使用mock object做单元测试,mock object如何插入?
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 bbb软讯网络 All Rigths Reserved.