通过使用具有受保护的析构函数的父类型实例化基 class 创建的可用内存
Free memory created by instantiating base class with parent type that has protected destructor
我认为这可能是一个非常简单的问题,但我是一名 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
中)将被放在堆上,我负责删除它。但我似乎无法删除它。
我无法更改 Container
中 child
的类型,因为我需要它接受 ChildA
和 ChildB
。考虑到 Parent
的析构函数受到保护,这是有道理的。我无法控制 Parent
或 Child
。它们是外部库的一部分。
如果有帮助,我正在使用的实际代码是一个名为 ArduinoJson 的库。
我正在尝试 return 来自函数的 DynamicJsonDocument
或 StaticJsonDocument<T>
,包装在采用 JsonDocument
:
的结构中
这是包含 JsonDocument
:
的结构
struct rpc_handler_result_t {
esp_err_t result;
JsonDocument *response;
};
return编辑自:
{
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
returns 的值存储在某处。但是看看您对 new
的调用——它取消引用该值并且 never 将它存储在任何地方。那么如何调用 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
returns 的值,以便您以后可以 delete
它。
- 不要尝试将本地对象的地址传递到函数之外。
您想要 .child = new ChildA()
,将 child
成员设置为指向由 new
创建的对象的指针,而不是指向某个临时本地对象的指针。如果需要,您可以临时保存值 new
returns,只需确保 .child
获得返回的值 new
而不是任何其他值。
还有:
Parent *child;
//Tried this, causes: munmap_chunk(): invalid pointer
~Container(){
delete &child;
}
这也是错误的。 &child
是什么类型? &child
是你从 new
那里得到的东西吗?这应该是 delete child;
.
我认为这可能是一个非常简单的问题,但我是一名 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
中)将被放在堆上,我负责删除它。但我似乎无法删除它。
我无法更改 Container
中 child
的类型,因为我需要它接受 ChildA
和 ChildB
。考虑到 Parent
的析构函数受到保护,这是有道理的。我无法控制 Parent
或 Child
。它们是外部库的一部分。
如果有帮助,我正在使用的实际代码是一个名为 ArduinoJson 的库。
我正在尝试 return 来自函数的 DynamicJsonDocument
或 StaticJsonDocument<T>
,包装在采用 JsonDocument
:
这是包含 JsonDocument
:
struct rpc_handler_result_t {
esp_err_t result;
JsonDocument *response;
};
return编辑自:
{
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
returns 的值存储在某处。但是看看您对 new
的调用——它取消引用该值并且 never 将它存储在任何地方。那么如何调用 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
returns 的值,以便您以后可以delete
它。 - 不要尝试将本地对象的地址传递到函数之外。
您想要 .child = new ChildA()
,将 child
成员设置为指向由 new
创建的对象的指针,而不是指向某个临时本地对象的指针。如果需要,您可以临时保存值 new
returns,只需确保 .child
获得返回的值 new
而不是任何其他值。
还有:
Parent *child;
//Tried this, causes: munmap_chunk(): invalid pointer
~Container(){
delete &child;
}
这也是错误的。 &child
是什么类型? &child
是你从 new
那里得到的东西吗?这应该是 delete child;
.