-2

可能重复:
为什么使用“新”会导致内存泄漏?

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

m_propertyManager(new coral::PropertyManager);

所以我把它修改为

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

我猜&Mgr它会自动删除,但 valgrind 再次报告泄漏。

4

2 回答 2

0

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 持有对无效内存的引用。

于 2013-01-09T12:09:54.907 回答
0

如果您使用 分配内存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
  • 实现 move ctor inPropertyManager并按值传递(这样m_propertyManager将隐式自动分配自己的实例PropertyManager
  • 使用静态分配(如您的第二个示例中所示),但将实例保留在该位置,它将至少m_propertyManager.
  • 在 m_propertyManager 中使用某种自动指针(如 std::shared_ptr 或 std::unique_ptr)
于 2013-01-09T12:10:47.963 回答