【问题标题】:Is there any way to check if pointer is dangling?有没有办法检查指针是否悬空?
【发布时间】:2011-12-01 07:54:02
【问题描述】:

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

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

有没有办法在对指针进行任何操作之前“检查”指针是否无效?显然,检查指针是否不等于 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;
}

方法对吗?

【问题讨论】:

    标签: c++ pointers mfc dangling-pointer


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

      • 感谢您的详细解释。我可以理解我应该找到解决方案而不是隐藏错误...但是设计的框架存在漏洞,我无法在短时间内更改。所以我暂时在寻找解决方法。我也尝试了智能指针,但没有成功。
      【解决方案3】:

      是的,您可以使用smart pointers

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • 我的指针对类应该是静态的。如果我使用智能指针,它仍然可以吗?
        • 完全没问题。您需要注意线程安全问题,但智能指针与原始指针没有什么不同。
        • 我认为这不重要。唯一困扰我的是你的框架本身是否可以让你的指针在没有任何事先通知的情况下悬空。看,您必须从智能指针中提取原始指针并将其传递给您的框架。如果它保证指针在调用后仍然有效,或者如果它变得无效会通知您 - 很好,去吧。
        猜你喜欢
        • 1970-01-01
        • 2010-09-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多