检查内存是否在堆上?

时间:2017-10-06 02:48:28

标签: c++ memory-management

我有一个班级constructor将对象的地址作为参数。

MyClass(OtherClass * otherClass);

在本课程的Destructor中,我尝试delete OtherClass的实例。

~MyClass() {
    if(otherClass != nullptr) {
        delete otherClass;
    }
}

我遇到的问题是,当我调用此constructor时,我使用stack中的元素而不是heap来调用它,因此我将其称为如下:< / p>

MyClass myClass(&amp; otherObject);

所以当myClass对象超出范围时,我得到一个例外。如果我在OtherObjectstack上声明了heap变量,我该如何表达?或者换句话说,我怎么知道我是否可以delete该对象?

1 个答案:

答案 0 :(得分:6)

虽然有一些特定于系统的方法可能会判断内存是来自堆还是来自堆栈,但这实际上并没有真正帮助:你可能有一个指向另一个对象成员的指针。堆。内存将在堆上,但您仍然不负责删除该对象。换句话说: not 沿着您所在的道路前进!

处理问题的正确方法是在界面中明确地清楚所有权语义,然后继续使用。您可以采取两种方向:

  1. 你的班级可以故意接管构造函数中传递的指针的责任!相反,您的类的用户有责任处理这些对象,以保证它们在您的对象存在时有效。如果您可以获得指向堆栈(或成员)对象的指针,则用户必须保证这些对象的有效性,并且对于其他方式,用户处理它们可能完全无关紧要,例如,通过std::unique_ptr<OtherClass>管理它们。
  2. 您的课程负责传递的所有对象,并且delete所有对象都将负责。调用者负责将指针传递给其他地方管理的对象,例如,堆栈或成员对象上的对象。
  3. 有一种混合方法,你的班级有时会对物品负责,但并非总是如此。但是,这种方法的实现实际上是上述两种方法的组合:您将合适的智能指针作为构造函数参数,并确保智能指针构造是用户的责任适合您班级的用户。例如,您的类可以使用std::shared_ptr<OtherClass>,其正常构造将delete对象。当用户想要传入指向另外拥有的对象的指针时,std::shared_ptr<OtherClass>将使用删除器来构造,该删除器 delete指针。这是一个简单的程序,演示std::shared_ptr的两种不同管理策略:

    #include <iostream>
    #include <memory>
    
    struct foo {
        char const* name;
        foo(char const* name)
            : name(name) {
            std::cout << "foo::foo(" << name << "): " << this << "\n";
        }
        ~foo() {
            std::cout << "foo::~foo(" << name << "): " << this << "\n";
        }
    };
    
    int main() {
        std::shared_ptr<foo>(new foo("heap"));
        foo f("stack");
        std::shared_ptr<foo>(&f, [](auto){});
    }