如何解决通过实例化具有保护析构函数的父类型的基类创建的空闲内存
我认为这可能是一个非常简单的问题,但我是 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
中)将被放置在堆上,我负责删除它。但我似乎无法删除它。
我无法更改 child
中 Container
的类型,因为我需要它同时接受 ChildA
和 ChildB
。考虑到 Parent
的析构函数是受保护的,这有点道理。我无法控制 Parent
或 Child
。它们是外部库的一部分。
如果有帮助,我正在使用的实际代码是一个名为 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
返回的值。但是您通过取消引用它并从不保存它立即摆脱了它。
所以:
- 您必须存储
new
返回的值,以便以后可以delete
。 - 不要试图从函数中传递本地对象的地址。
您想要 .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 举报,一经查实,本站将立刻删除。