【问题标题】:How to delete smart pointer to dynamically allocated object?如何删除指向动态分配对象的智能指针?
【发布时间】:2017-09-23 18:44:27
【问题描述】:

我创建了一个迭代器,当它被取消引用时,它返回一个指向动态分配的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(),但这些都无法编译。

【问题讨论】:

  • 我认为您误解了智能指针的实际含义和作用。
  • 你为什么这么认为?
  • 这对在 smart 指针中,即您不需要手动释放内存,智能指针会为您完成 :)
  • 啊……我明白了。我现在真的觉得很傻。我知道智能指针会为我删除它们的内容,但不知何故我忘了哈哈
  • 解析器对象必须确保您正在迭代的pair 上的引用计数不能达到零并触发delete(否则代码将已经存在竞争条件并被破坏)。所以,你可以说[const] auto&amp; record = **it; 来获得对pair 的引用,这比在共享指针中两次摆弄原子使用计数更简单、更快捷。

标签: c++ memory-management shared-ptr smart-pointers


【解决方案1】:

shared_ptr 旨在在不再需要时自动删除他们管理的对象。当不再有共享指针指向该对象时会发生这种情况(例如,所有指向同一个对象的共享指针都被删除,或者reset 指向另一个对象)。

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

unique_ptr 是另一种智能指针。它们旨在保留已分配对象的所有权,并在唯一指针本身被销毁时销毁该对象。

同样,不需要自己删除对象。 unique_ptr 的创建是为了让你摆脱这个职责。但是在这里,您可以根据需要通过reseting 指针销毁托管对象。由于指针是唯一的,因此这里没有创建悬空指针的风险。

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

【讨论】:

    【解决方案2】:

    对于我的智能指针,它有重载的操作符删除,我使用

    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 可以理解不带 & 的删除

    // 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 没有

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-06
      • 1970-01-01
      • 2012-09-10
      • 1970-01-01
      • 2016-03-02
      • 1970-01-01
      • 2021-03-29
      • 1970-01-01
      相关资源
      最近更新 更多