14

我有一个代码,我使用指针访问一些数据块。在极少数情况下,数据块的一些成员是空的,因此指针变得悬空。事实上,我得到了正确的指针,但是当试图用指针做某事时程序崩溃了。

通常的建议是避免这种类型的使用。但遗憾的是,我使用的框架要求我使用这种类型的数据访问方法。

有没有办法在对指针进行任何操作之前“检查”指针是否无效?显然,检查指针是否不等于 NULL 不起作用。我也试过这个:

try
{
    CString csClassName = typeid(*pMyPointer).name();  // Check error condition
    // The line below fails due to dangling pointer (data block is not valid).
    hr = pMyPointer->MyPointerMethod(); 
}
catch(bad_typeid)
{
    return E_FAIL;
}
catch(...)
{
    return E_FAIL;
}

这是正确的方法吗?

4

4 回答 4

9

无法检查原始指针是否有效。当您访问它们时,不能保证无效的指针会失败。您需要使用某种形式的智能指针,而不是使用原始指针。

于 2011-10-05T09:25:57.470 回答
7

我认为您正在寻找错误的方向。您可能有一个错误,您没有正确初始化指针,过早删除对象并尝试在删除指针后重用指针或类似的东西。如果是这种情况,您应该专注于确定发生这种情况的原因并修复错误,而不是试图找到隐藏错误的方法。

至于您与typeid操作员一起使用的方法,答案是它无效。对于不包含虚函数的类型的对象,typeid运算符在编译时根据指针的静态类型解析。对于包含至少一个虚函数的对象,它会在运行时解析,但typeid(p)使用无效指针调用是未定义的行为,并且以与它似乎工作的相同方式可能会崩溃。

建议的智能指针的使用可能取决于库的实际作用以及您是否可以始终传递智能指针。一般来说,使用智能指针进行内存管理是一个好主意,这反过来又可以保证指针被正确初始化(如果问题是初始化,则修复)并且因为您不再delete手动,如果问题是提前删除将不再发生。但请注意,虽然这可能会解决问题,但我仍然认为您需要了解为什么指针在您的应用程序中无效,因为这可能是更大问题的征兆。

现在,关于如何检查指针是否悬空的原始问题,您无法在程序中执行此操作,但您可以在内存调试器(linux 中的 valgrind、Purify 或 linux 中的其他一组)中运行程序,并且该工具将能够帮助您确定指针是否从未初始化,或者您是否在错误使用之前将内存释放到系统。

于 2011-10-05T10:14:53.607 回答
3

是的,您可以使用智能指针

于 2011-10-05T09:26:20.620 回答
2

您不需要智能指针。它们只是处理此问题的一种可能方法。

您可以使用相互引用:在被引用对象 (referencee) 中,一个引用列表返回到引用它的那些对象 (referencers)。当需要释放引用时,首先运行其引用列表并将它们用于指向引用的任何属性设置为 null(通常您想事先知道这将是哪个属性),然后释放参考人。

于 2014-11-09T15:41:38.203 回答