回调函数中删除对象引发的隐晦非法访问崩溃问题

5 篇文章 0 订阅

回调函数,这里说的是一种笼统的概念,泛指一个对象或者一个过程调用陷入另一个对象或过程。本文想要描述的就是在回调函数中执行释放、删除动作去销毁调用调用者相关联的内容,导致访问非法。

下面用一段代码来简述一下这个坑是怎么产生的:

class ISomeFace
{
public:
    void callback(CBase* pBase)=0;
}
class CCallee:public ISomeFace
{
public:
    void callback(CBase* pBase);
    {
        handleCBase(pBase);
        if(pBase == WORK_DONE)
        {
            delete pBase;
        }
    }
}

class CCaller: public CBase
{
public:
    virtual ~CCaller()
    {
	if(mBuffer)delete[] mBuffer;
    }
    void doSomething(ISomeFace* sf)
    {
	if(mBuffer==NULL) mBuffer = new char[1024];
        sf->callback(this);
        doNextActionWith(mBuffer);
    }
private:
    char* mBuffer;
}

当调用doSomething的时候进入了sf->callback,在callback中因为达成了某些条件,代码决定删掉pBase,也就是CCaller。可以看到~CCaller中释放了mBuffer。这样当调用完毕回到doSomething的doNextActionWith,此时访问mBuffer就成为非法访问。

这种问题比较隐晦,有时候因为mBuffer刚被释放,立即访问不会马上产生异常,或者因为doNextActionWith做的比较严谨程序长时间都不会出现问题,但是保不齐哪天开始大规模出事!

另外实际项目中,这种销毁关系不会那么明显,可能经过多层调用后辗转间接执行了销毁,特别是仅在小概率条件发生时才销毁,这样就产生了小概率崩溃发生,非常难于调试。所以我建议的解决办法是马上去review所有在回调中执行的销毁动作,最好理清间接的销毁动作;如果是linux平台可以用valgrind的memcheck来协助你找到这样的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值