关于一个默认拷贝函数、互斥引发的堆错误的bug(散分贴)

Smile_Tiger 2014-12-21 09:48:13
前不久某个项目经常出问题,错误的地方总是出现在互斥的那个地方,而且提示有堆错误。分析了好几天都没解决,只好到客户现场来解决问题。

1. 首先我实现了一个很简单的互斥类


#pragma once

#include "windows.h"

class csClass
{
public:
csClass() : m_bEnable(true)
{
::InitializeCriticalSection(&m_cs);
}
~csClass()
{
::DeleteCriticalSection(&m_cs);
}

void Enable(bool b)
{
m_bEnable = b;
}

void Lock()
{
if(m_bEnable)
::EnterCriticalSection(&m_cs);
}

void Unlock()
{
if(m_bEnable)
::LeaveCriticalSection(&m_cs);
}

public:
CRITICAL_SECTION m_cs;
bool m_bEnable;
};

class csScope
{
public:
csScope(csClass* cs):m_cs(cs)
{
if(m_cs)
m_cs->Lock();
}

~csScope()
{
if(m_cs)
m_cs->Unlock();
}
protected:
csClass* m_cs;
};


具体的用法大家应该知道,定义一个互斥变量 csClass mycs; 然后在需要互斥的地方写 csScope Scope(&mycs);

2. 可是我有个地方写错了,写成了 csClass Scope(mycs);
csClass有个默认的构造拷贝函数 csClass(const csClass& obj); 它将mycs对象复制给了Scope

3. 我又专门写了一个测试小例子:


// testaaa.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "csDef.h"

int _tmain(int argc, _TCHAR* argv[])
{
csClass g_cs;

for(int i=0;i<100;i++)
{
csClass Scope(g_cs);
}

int debug = 1;

return 0;
}



4. 经过运行测试,程序会在循环到i=11的时候,在csClass的析构函数中的::DeleteCriticalSection()那里出错(这也是这个bug很难用某种重复操作的手段来再现错误,你操作的次数少于11就不会出错)
5.经过分析,循环体中的 csClass Scope(g_cs); 这句话,不会进入构造函数中(因为进入的是构造拷贝函数),也就是说不会调用::InitializeCriticalSection(),却调用了10次::DeleteCriticalSection()而没有出错,调用第11次出错了。这个11应该和CRITICAL_SECTION的系统设计有关系.

6.把循环次数改为10,那么程序运行到退出main()函数时,g_cs将要析构,此时引发了g_cs的堆错误


--------------------------
对此问题的初步分析已经完毕,更深层次的研究我没有进行,期待大神来说一说

有一个经验上的问题困扰我:如何迅速地发现这类堆错误的bug在哪儿?这次的bug算我运气好,发现那里些错误,如果我没发现那里写错,该怎么发现错误的地方呢?
...全文
147 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
ri_aje 2014-12-21
  • 打赏
  • 举报
回复
把基础打牢靠就能避免这类错误了,c++ 不是有条 rule of three (http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29) 原则吗,说的是 dtor, copy ctor, copy assignment operator 要么一起出现,要么都用默认的。主楼的错误归根结底是 csClass 不支持复制构造,结果你又不禁止复制构造。
Johnblx 2014-12-21
  • 打赏
  • 举报
回复
我没有看懂问题。 还是顶一下
fly_dragon_fly 2014-12-21
  • 打赏
  • 举报
回复
名字,类名看不出来是做什么的

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧