0

假设我们有一个包含指向另一个对象的指针成员的类。如果我在析构函数中删除该指针,我会得到一个错误(我明白为什么)。

我的问题是:是否有可能在没有内存泄漏的情况下克服这个问题?

这是我在做什么的演示。

class A {
    public:
    ~A() { cout<< "~A()" <<endl; }
};

class B {
    A *pA;
    public:
    B(A* pA) {
        this->pA = pA;
    }
    ~B() { 
                delete pA;
        cout<<"~B()"<<endl;
    }
};

int main() {
    A a;
    {
        B b2(new A()); //deletes A, deletes B, no memory leaks
    }
    {
        B b(&a); //deletes A, error.
    }

    return 0;
}
4

3 回答 3

2

首先,这不是内存泄漏,而是未定义的行为,是一个更严重的问题。试图从错误的区域释放内存。
一个应该delete/delete[]/free()只在相应new/new[]/malloc()的 .

没有完全证明和架构独立的方式,只要坚持良好的编程实践。

可能并不总是完美的,但一种方法是重载newdelete保持std::map类似的数据结构。每当new被调用时,添加指向它的指针。delete您可以检查指针是否存在,分配是否属于类型newnew[]
这肯定会影响您的性能,因此您需要将其保持在调试模式下。

于 2013-03-20T07:12:24.520 回答
2

您有两个对象认为它们拥有一个动态分配的对象并尝试删除它。解决方案是决定谁应该拥有该对象,并在适当的智能指针的帮助下实现正确的复制/分配行为:

  1. AB处理动态分配的对象吗?无法从原始指针中知道这一点,因此必须修改设计以涵盖一种情况或另一种情况。假设动态对象分配,那么
  2. 每个对象都拥有自己的副本: 实现Aor中的三个规则B,并且只有两个中的一个 delete。您可以使用作用域指针来简化内存管理(boost_scoped_ptrstd::unique_ptr)。
  3. 唯一所有权:单个对象拥有副本:使用std::unique_ptr。禁止复制和分配,允许移动复制和移动分配
  4. 共享所有权:没有人/每个人都拥有该对象。当没有人引用它时它会被删除:使用std::shared_ptr
于 2013-03-20T07:15:01.293 回答
1

你必须告诉B它什么时候拥有指针,什么时候不拥有。

添加一个额外的标志,告诉何时

class B {
    bool owner;
    A *pA;
    public:
    B(A* pA, bool bOwner) : owner(bOwner) {
        this->pA = pA;
    }
    ~B() { 
        if (owner)
            delete pA;
        cout<<"~B()"<<endl;
    }
};

int main() {
    A a;
    {
        B b2(new A(), true); //deletes A, destroys B, no memory leaks
    }
    {
        B b(&a, false); //destroys B, ok.
    }

    return 0;
}
于 2013-03-20T07:19:30.083 回答