指向已销毁类失效的指针

Posted

技术标签:

【中文标题】指向已销毁类失效的指针【英文标题】:Pointer to destroyed class invalidation 【发布时间】:2019-01-19 16:18:13 【问题描述】:

我有一个很多指针指向的对象。他们经常尝试访问数据。然而,在某些时候,这个对象可能会被破坏。如何在销毁对象后立即有效地更新这些指针,以免它们指向未分配的内存并导致未定义的行为?

我的想法是列出需要更新为nullptr 的指针。这将在对象的析构函数中调用。丑陋的混乱和每件可能被释放的东西的大量工作。

也许这些智能指针对这些情况有一些用处(从未使用过它们)。 C++ 程序员如何处理这样的事情?

【问题讨论】:

en.cppreference.com/w/cpp/memory/weak_ptr,尤其是en.cppreference.com/w/cpp/memory/weak_ptr/expired 引用计数怎么样? 【参考方案1】:

您只需要使用std::shared_ptr 和std::weak_ptr。

shared_ptr 非常聪明,您无需删除它们,当没有人再引用它们时,它们将被删除。然后,任何与此 shared_ptr 相关的 weak_ptr 都会被告知,并且它没有访问未分配内存的风险。

当它需要它时,weak_ptr 将尝试lock() 并创建一个本地shared_ptr。如果原始的shared_ptr 被删除,lock() 将无法创建本地的shared_ptr,您将安全地知道原始指针已被删除。

// Example program
#include <iostream>
#include <assert.h>
#include <memory>

int main()

    std::shared_ptr<int> pI( new int(3) );
    std::weak_ptr<int> wI( pI );

    
        // check if weak_ptr still "points" to some valid data:
        std::shared_ptr<int> pICopy = wI.lock();
        assert( pICopy != NULL );
        std::cout << "pI still valid " << *pICopy << std::endl;
    

    pI.reset(); // this is equivalent to regular delete with shared_ptr

    
        // check if weak_ptr does not "point" to any valid data:
        std::shared_ptr<int> pICopy = wI.lock();
        assert( pICopy == NULL );
        std::cout << "pI not valid anyore" << std::endl;
    

【讨论】:

这正是我想要的。猜猜是时候学习新的指针系统了...【参考方案2】:

丑陋的混乱和每件可能被释放的东西的大量工作

不要在析构函数中进行清理。做一个单独的函数,在析构函数中调用。你可以从其他对象的析构函数中调用这个常用的清理函数。

【讨论】:

以上是关于指向已销毁类失效的指针的主要内容,如果未能解决你的问题,请参考以下文章

vector之二(迭代器失效与解决)

vector之二(迭代器失效与解决)

C++ 迭代器失效

vector迭代器失效

迭代器失效

echarts map显示多组数据markpoint effect失效,是啥原因