如何使用动态强制转换检测指针的删除
How is the deletion of a pointer detected using dynamic cast
如图所示,可以使用dynamic_cast
来检测已删除的指针:
#include <iostream>
using namespace std;
class A
{
public:
A() {}
virtual ~A() {}
};
class B : public A
{
public:
B() {}
};
int main()
{
B* pB = new B;
cout << "dynamic_cast<B*>( pB) ";
cout << ( dynamic_cast<B*>(pB) ? "worked" : "failed") << endl;
cout << "dynamic_cast<B*>( (A*)pB) ";
cout << ( dynamic_cast<B*>( (A*)pB) ? "worked" : "failed") << endl;
delete pB;
cout << "dynamic_cast<B*>( pB) ";
cout << ( dynamic_cast<B*>(pB) ? "worked" : "failed") << endl;
cout << "dynamic_cast<B*>( (A*)pB) ";
cout << ( dynamic_cast<B*>( (A*)pB) ? "worked" : "failed") << endl;
}
输出:dynamic_cast<B*>( pB) worked
dynamic_cast<B*>( (A*)pB) worked
dynamic_cast<B*>( pB) worked
dynamic_cast<B*>( (A*)pB) failed
说明检测到虚函数表的删除。
但我想知道这是怎么可能的,因为我们不覆盖释放的内存?
这个解决方案是完全可移植的吗?
谢谢
首先,尝试以任何形式使用已删除的对象都会导致未定义的行为:您看到的任何结果都可能发生!
观察到的行为的原因很简单,对象在销毁期间改变了类型:从一个具体类型的对象,它通过层次结构中的所有类型改变。在每个点上,虚函数都会发生变化,虚函数表(或类似的表)也会被替换。dynamic_cast<...>()
只是检测对象所在位置存储的字节的变化。
如果你想表明这种技术不可靠地工作,你可以把删除的内存的内容设置为一个随机的位模式或最派生类型的对象的位模式:一个随机的位模式可能会导致崩溃,memcpy()
可能会声称对象仍然存在。当然,因为它是未定义的行为,所以任何事情都可能发生。
这是3.8的一个相关章节[basic]。生活]第5段:
在对象的生命周期开始之前,但在对象将要占用的存储空间被分配之后,或者在对象的生命周期结束之后,在对象所占用的存储空间被重用或释放之前,任何指向对象将要或曾经所在的存储位置的指针都可以被使用,但只能以有限的方式使用。对于正在构建或销毁的对象,请参见12.7。否则,这样的指针指的是已分配的存储(3.7.4.2),并且将该指针当作
程序有未定义的行为void*
类型的指针使用,是定义良好的。通过这样的指针进行间接操作是允许的,但是产生的左值只能以有限的方式使用,如下所述。如果:
- …
- 指针被用作dynamic_cast(5.2.7)的操作数. ...
奇怪的是,dynamic_cast
的最后一个项目的例子并没有使用dynamic_cast
。
相关文章:
- SFINAE - 检测类型 T 是指针、数组还是带有随机访问运算符的容器,以及给定的值类型
- 对于循环不循环和检测字符数组 [指针和字符数组]
- 对于实际指针类型,用于检测类似指针(可取消引用)类型的模板函数失败
- 未检测到的空指针
- 未检测到越界指针算法?
- ***检测到的GLIBC *** MS2:free():无效指针:0xB7526FF4 ***
- gcc-如何检测基于指针的内存访问
- glibc 检测到 *** free() 无效指针
- "空指针已通过",用于检测轮廓
- *** glibc检测到*** free():无效的指针:
- 为引用计数的智能指针检测内存泄漏的设计模式
- c++提升线程glibc检测到无效指针
- 检测到指针引用可能存在内存泄漏
- 检测"内存泄漏"时,瓦尔格林德的真实指针是什么?
- glibc 检测到 free() 无效指针
- 为什么此循环不检测空指针?
- 如何检测或避免使用未初始化C++指针
- 如何使用动态强制转换检测指针的删除
- 如何检测指针是否已删除并安全删除
- 方法检测指针是否指向…确切的地点