【问题标题】:how to delete memory occupied by new operator in C++ [duplicate]如何删除C++中new运算符占用的内存[重复]
【发布时间】:2012-12-23 11:17:50
【问题描述】:

可能重复:
Why does the use of ‘new’ cause memory leaks?

我是 C++ 内存分析的新手。 Valgrind 报告了这一行的泄漏

m_propertyManager(new coral::PropertyManager);

所以我修改为

coral::PropertyManager Mgr;
m_propertyManager(&Mgr);

我猜&Mgr 已被自动删除,但 valgrind 再次报告此漏洞。

【问题讨论】:

    标签: c++


    【解决方案1】:

    new coral::PropertyManager 在堆上分配一个新的 PropertyManager,但因为它是一个临时变量,您永远不会释放它。这是标准的 Java 习惯用法,因为 Java 是一种垃圾收集语言,GC 会负责为您释放这个悬空引用。

    如果你出于某种原因想在这里使用new,正确的做法如下:

    auto *pm = new coral::PropertyManager; // auto is C++11 syntax
    m_propertyManager(pm);
    delete pm; // when you're done using it
    

    您的第二个选项是正确的,因为它将Mgr 分配为堆栈上的自动变量,该变量将在函数退出时释放。 m_propertyManager(&Mgr); 将 Mgr 的 地址 传递给函数,这将允许它修改 Mgr 对象(尽管将 Mgr 作为引用传递可能会更好)。

    请注意,如果 m_propertyManager 是在当前范围退出后仍然存在的对象,并且如果它在某处存储对 Mgr 的引用,那么当您退出当前范围并且 Mgr 对象被销毁时,您会发现 m_propertyManager 持有对无效的内存。

    【讨论】:

    • 最好使用 std::unique_ptr 像 m_propertyManager(std::unique_ptr(new coral::PropertyManager));
    • @mgr:我可能弄错了,但这不是因为您不能将唯一指针的副本传递给函数吗?在这个用例中,std::shared_ptr 不是更明智的选择吗,当我错了时纠正我。
    • 是的,你是对的,这里需要一个共享指针。
    【解决方案2】:

    如果您使用new 分配内存,则必须使用delete 在某处释放它。如果m_propertyManager 不应该管理PropertyManager 的生命周期,它只会丢弃指针,留下分配的内存并且无法访问。

    另一方面,您的第二个解决方案将崩溃​​。看:

    {
        coral::PropertyManager Mgr;
        m_propertyManager->SetManager(&Mgr); // You pass pointer to Mgr here
    }
    // Here Mgr no longer exists, so m_propertyManager
    // now contains the pointer to non-existing object
    

    您应该:

    • 动态创建PropertyManager(使用new),在某处持有指向它的指针,并在某个时候使用delete显式释放它;
    • PropertyManager 中实现移动ctor 并按值传递(这样m_propertyManager 将隐式自动分配其自己的PropertyManager 实例)
    • 使用静态分配(如您的第二个示例中所示),但将实例保留在该位置,至少只要m_propertyManager,它就会保持活动状态。
    • 在 m_propertyManager 中使用某种自动指针(如 std::shared_ptr 或 std::unique_ptr)

    【讨论】:

      猜你喜欢
      • 2018-07-16
      • 1970-01-01
      • 1970-01-01
      • 2011-01-13
      • 2021-05-08
      • 1970-01-01
      • 2011-03-09
      相关资源
      最近更新 更多