0

我认为这可能是一个非常简单的问题,但我是一名 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(in MakeStruct) 将被放置在堆上,并且我负责删除它。但我似乎无法删除它。我无法更改 in 的类型,child因为Container我需要它同时接受 aChildA和 a ChildB。考虑到受保护的析构函数,这有点道理ParentParent我无法控制Child。它们是外部库的一部分。

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

我试图从一个函数返回 aDynamicJsonDocument或 a StaticJsonDocument<T>,包装在一个结构中,采用 a 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;
}
4

1 回答 1

1

当您最终调用时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;

于 2021-02-28T19:54:23.060 回答