【发布时间】:2016-01-14 12:14:20
【问题描述】:
由于某些原因,我们的应用程序中的指针可能已经被删除:
IPolymorphicObject* p_object = CreateObject();
某处 p_object 将被删除(通过 delete 或卸载分配它的模块)
delete p_type;
另一个使用 p_object 保存值的代码,让它成为 mp_object。
mp_object->SomeMethod();
由于 mp_object 已被删除 - 我们发生了崩溃。 我知道最好的方法是切换到shared_ptr/weak_ptr,但是现在它需要大量的重构,这就是为什么我找到了另一个解决方案——如何检查指针的有效性。
我知道 dynamic_cast 将返回指向内存中实际对象偏移量的指针。
我也知道 dynamic_cast(p_invalid_pointer) 会抛出一个异常 non_rtti_object 我可以捕捉到我因此编写验证方法:
template<class T>
bool IsPointerValid(T* ip_ptr)
{
try
{
dynamic_cast<void*>(ip_ptr);
}
catch(...)
{
return false;
}
return true;
}
最终代码如下所示:
if(IsPointerValid(mp_object)) mp_object->SomeMethod();
我知道这将是一个非常糟糕的解决方案,应该避免。
我的问题是:如果指向多态对象的指针无效,IsPointerValid 是否总是返回 false?
【问题讨论】:
-
我强烈怀疑你在这个世界的任何保证之外!绝对是语言标准。可能是通过执行。无论如何,它是哪个实现?
-
你添加了 C 标签 - 为什么? C 不是 C++ 不是 C!
-
以任何方式使用杂散指针,除了重新初始化它(即分配它指向有效的东西)总是会导致未定义的行为。
-
即使你发现指针中包含了某个“多态对象”的地址,它也很可能是某个new对象碰巧重用了被删除对象的内存空间。
-
我使用 Visual Studio 2013 x64 库中的 dynamic_cast 实现。对于所有具有无效指针的情况,它都运行良好。但我知道它确实是特定于实现的,并且取决于编译器/链接器/目标平台。我发现在 Linux 上它会崩溃,因为指针指向已经空闲的内存。