注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

C++小知识35--队列push出现bad_alloc错误分析  

2012-10-10 16:02:09|  分类: C++(VC)编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

队列push出现bad_alloc错误分析
今天调试一个程序,经常出现bad_alloc这个错误,特别是连接数量上来后,过几分钟就会出现这个错误.在网上查了下资料,stl::bad_alloc这个错误多出现在内存耗尽或者内存碎片太多的时候儿.出现错误的地方在:
    ::EnterCriticalSection(&m_CS);
    m_recvMSG.push(Msg);
    ::LeaveCriticalSection(&m_CS);
当中的push中,很奇怪.网上的资料说VECTOR在分配内存的时候儿,是按照2的指数增长来分配的,这样的目的是为了防止反复的分配和释放内存,而且他的例子达到了恐怖的一百多G,可是这个程序只有几M时就报这个错误,觉得应该不是内存耗尽.应该是碎片或者反复分配内存,造成的内存分配错误.看其源码:
 void push_back(const _Ty& _Val)
  { // insert element at end
  this->_Orphan_all();
  _PUSH_BACK_BEGIN;
  _Cons_val(this->_Alval,
   this->_Map[_Block] + _Newoff % _DEQUESIZ, _Val);
  _PUSH_BACK_END;
  }
其中宏:
#define _DEQUESIZ (sizeof (value_type) <= 1 ? 16 : sizeof (value_type) <= 2 ? 8 : sizeof (value_type) <= 4 ? 4 : sizeof (value_type) <= 8 ? 2 : 1)
这种三目运算符的多个连续运算是从左到右,如果一旦确定值就不再进行下一步的运算,否则一直运算到最后.
再跟下去:
template<class _Ty> inline
 _Ty _FARQ *_Allocate(_SIZT _Count, _Ty _FARQ *)
 { // allocate storage for _Count elements of type _Ty
 void *_Ptr = 0;

 if (_Count <= 0)
  _Count = 0;
 else if (((_SIZT)(-1) / sizeof (_Ty) < _Count)
  || (_Ptr = ::operator new(_Count * sizeof (_Ty))) == 0)
  _THROW_NCEE(bad_alloc, 0);

 return ((_Ty _FARQ *)_Ptr);
 }
很明显,是_Ptr = ::operator new(_Count * sizeof (_Ty))) == 0出错了,其代码如下:
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
        {       // try to allocate size bytes
        void *p;
        while ((p = malloc(size)) == 0)
                if (_callnewh(size) == 0)
                {       // report no memory
                static const std::bad_alloc nomem;
                _RAISE(nomem);
                }

        return (p);
        }
也就是说malloc的时候儿出了错,明白了原因,再反推回去,应该就是连续分配内存出现了内存碎片.
一定要小心.

  评论这张
 
阅读(1362)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017