回调函数中删除对象引发的隐晦非法访问崩溃问题
2015-05-18 23:23
393 查看
回调函数,这里说的是一种笼统的概念,泛指一个对象或者一个过程调用陷入另一个对象或过程。本文想要描述的就是在回调函数中执行释放、删除动作去销毁调用调用者相关联的内容,导致访问非法。
下面用一段代码来简述一下这个坑是怎么产生的:
当调用doSomething的时候进入了sf->callback,在callback中因为达成了某些条件,代码决定删掉pBase,也就是CCaller。可以看到~CCaller中释放了mBuffer。这样当调用完毕回到doSomething的doNextActionWith,此时访问mBuffer就成为非法访问。
这种问题比较隐晦,有时候因为mBuffer刚被释放,立即访问不会马上产生异常,或者因为doNextActionWith做的比较严谨程序长时间都不会出现问题,但是保不齐哪天开始大规模出事!
另外实际项目中,这种销毁关系不会那么明显,可能经过多层调用后辗转间接执行了销毁,特别是仅在小概率条件发生时才销毁,这样就产生了小概率崩溃发生,非常难于调试。所以我建议的解决办法是马上去review所有在回调中执行的销毁动作,最好理清间接的销毁动作;如果是linux平台可以用valgrind的memcheck来协助你找到这样的问题。
下面用一段代码来简述一下这个坑是怎么产生的:
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来协助你找到这样的问题。
相关文章推荐
- javascript 直接创建对象与间接创建对象 私有函数不能访问this变量 是否使用var声明变量几个问题探讨
- Qt中控件对象访问成员函数时应该注意的问题
- C++利用类静态变量,实现伪类对象空指针成功访问含有成员变量的成员函数而不崩溃
- 从内存角度分析:数组删除自己内部指定对象和通过函数形参改值问题
- 因文件对象未释放导致文件无法删除问题处理或访问
- C++基类成员函数访问派生类对象的基类成员问题
- 解决R语言中save()函数保存对象集合问题-->《R语言编程艺术》P195
- php中的一个时间函数引发的问题
- 简单下载单张图片进行回调,下载对象为空的问题
- C++中用函数返回值初始类对象时的一个问题
- 用Registry Trash Keys Finder删除Total Uninstall注册表中无用信息,解决注册时必须强制网络访问问题
- this指针访问成员函数问题
- 派生类的对象访问基类中被派生类覆盖或隐藏了的函数或变量
- 子窗口和父窗口的函数或对象能否相互访问 (转载)
- is_uploaded_file函数引发的问题
- 回调函数参数不同,导致程序崩溃.
- C++使用mysql 库访问MYSQL数据库,mysql_init函数破坏内存的问题
- 从 DataTable 对象中删除 DataRow 对象 遇到的问题
- 使用replace和strip函数删除open()函数独处的回车问题
- 在win10系统下搭建网站遇到“无法枚举容器中的对象,访问被拒绝”问题