微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过实例化具有保护析构函数的父类型的基类创建的空闲内存

如何解决通过实例化具有保护析构函数的父类型的基类创建的空闲内存

我认为这可能是一个非常简单的问题,但我是 C++ 开发人员,因为沃尔玛肉类柜台的人都是屠夫。

我有

class Parent{
    protected:
        ~Parent(){};
};

class ChildA : public Parent{

};

struct Container{
    Parent *child;

    //Tried this,causes: munmap_chunk(): invalid pointer
    ~Container(){
        delete &child;
    }
};

Container MakeStruct(){
    ChildA child = *new ChildA();
    return Container { .child = &child };
}

int main()
{
    Container cont = MakeStruct();

    //Tried this,causes: "Parent::~Parent()" is inaccessible
    delete cont.child;
}

如您所见,我使用 new 创建一个 ChildA,因为我需要它比 MakeStruct 函数的寿命更长。所以我知道这意味着 child(在 MakeStruct 中)将被放置在堆上,我负责删除它。但我似乎无法删除它。 我无法更改 childContainer 的类型,因为我需要它同时接受 ChildAChildB。考虑到 Parent 的析构函数是受保护的,这有点道理。我无法控制 ParentChild。它们是外部库的一部分。

如果有帮助,我正在使用的实际代码一个名为 ArduinoJson 的库。

我试图从一个函数中返回一个 DynamicJsonDocument一个 StaticJsonDocument<T>,包装在一个带有 JsonDocument 的结构中:

这是包含 JsonDocument 的结构体:

struct rpc_handler_result_t {
    esp_err_t result;
    JsonDocument *response;
};

返回自:

{
    const int len = JSON_OBJECT_SIZE(1);
    StaticJsonDocument<len> reply = *new StaticJsonDocument<len>;

    reply["MaxOutput"] = Configuration::GetMaxOutputAmps();

    rpc_handler_result_t res = {
        .result = ESP_OK,.response = reply
    };

    return res;
}

解决方法

当您最终调用 delete 时,您必须准确地将您从 new 获得的值传递给它。因此,您必须new 返回的值存储在某处。但是看看您对 new 的调用——它取消引用该值并且从不将它存储在任何地方。那么你怎么能调用delete?!

 Container MakeStruct(){
    ChildA child = *new ChildA(); // The value returned by new is lost here
    return Container { .child = &child }; // child is a local object here
}

这都是错的。您可以通过调用 new 创建一个新对象。但是您不会将返回的值 new 存储在任何地方。现在,child 是一个临时对象,其值是根据您使用 new 分配并泄漏的对象的值复制构造的。

然后,您将创建的临时 child 对象的地址保存在堆栈中。但是在您return之后该对象将不存在。

您想要做的是保存 new 返回的。但是您通过取消引用它并从不保存它立即摆脱了它。

所以:

  1. 必须存储 new 返回的值,以便以后可以delete
  2. 不要试图从函数中传递本地对象的地址。

您想要 .child = new ChildA(),将 child 成员设置为指向由 new 创建的对象的指针,而不是指向某个临时本地对象的指针。如果需要,您可以临时保存 new 返回的值,只需确保 .child 获得返回的值 new 而不是任何其他值。

还有:

Parent *child;

//Tried this,causes: munmap_chunk(): invalid pointer
~Container(){
    delete &child;
}

这也是错误的。 &child 是什么类型? &child 是你从 new 那里得到的吗?这应该是 delete child;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?