如何删除指向动态分配对象的智能指针?

6

我创建了一个迭代器,当解引用该迭代器时返回一个指向动态分配的 std::pairstd::shared_ptr 的副本(在迭代器内部使用 new 创建)。 迭代器正常运行,但是想要在循环结束时释放 pair,以防止内存泄漏。

for (auto it = parser.begin(); it != parser.end(); ++it) {
    shared_ptr<pair<string, string>> record = *it;
    // Analysis of pair
    // delete pair with delete, or reset
}

然而,我在释放 pair 上遇到了困难。我已经尝试过 delete recorddelete *recordrecord.reset(),但是这些方法都不能通过编译。


3
我认为你误解了智能指针的实际含义和作用。 - Rakete1111
3
你为什么这样想? - Jon Deaton
3
这对数据存储在一个“智能”指针中,也就是说,您不需要手动释放内存,智能指针会为您完成 :) - Rakete1111
啊...我明白了。现在我感觉真的很傻。我知道智能指针会为我删除它们的内容,但不知怎么的,我竟然忘了哈哈。 - Jon Deaton
解析器对象必须确保正在迭代的“pair”的引用计数不会达到零并触发“delete”(否则代码已经存在竞争条件并且已经损坏)。因此,您可以只说[const] auto& record = **it;来获取对“pair”的引用,这将比两次操作共享指针中的原子使用计数更简单和更快。 - Tony Delroy
2个回答

12

shared_ptr 被设计用于自动删除其所管理的对象,一旦不再需要它。当没有任何 shared pointer 再指向该对象时(例如,所有指向同一对象的 shared pointers 都被删除或通过 reset 指向另一个对象),这就会发生。

你无需自己删除它。按照设计,甚至没有办法直接删除对象,因为这可能导致一些悬空指针和不一致性。

unique_ptr 是另一种智能指针。它们被设计来持有分配的对象,并在唯一指针本身被销毁时销毁该对象。

同样,你不需要自己删除对象。unique_ptr 被创建出来就是为了让你免除这个责任。但是你可以通过 reset 指针来销毁管理的对象,因为指针是唯一的,所以这里不会产生悬空指针的风险。

最后,还有weak_ptr。它们不拥有一个对象,而是引用由一些 shared_ptr 管理的对象。这样做的想法是,存在 weak_ptr 不会阻止对象被删除。由于 weak_ptr 不拥有对象,无论你做什么它都不能删除它。


0

对于我的智能指针,它有重载的operator delete,我使用

struct DeleteIt
{
        template < typename T >
        void operator() ( const T* ptr ) const
        {
                delete ptr ;
        }

        template < typename T >
        void operator() ( const safeptr< T >& ptr ) const
        {
                delete &ptr ;
        }
} ;

像7.3和8.2这样的新GCC可以理解没有&的delete操作符

// this is okay for modern GCC
for ( std::vector< safeptr< Item > >::const_iterator it = items.begin () ; it != items.end () ; ++ it )
{
        delete *it ;
}

// this works with any GCC
for ( std::vector< safeptr< Item > >::const_iterator it = items.begin () ; it != items.end () ; ++ it )
{
        delete &( *it ) ;
}

但是像4.0.x这样的GCC不支持


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接