当你在函数范围内创建一些指针时,当函数超出范围时会发生什么?它们会被销毁吗?或者我应该在某些时候对它们进行删除?
void XMLDocument::AddNode(XMLNode& node)
{
std::string val = node.GetNodeName();
TiXmlElement* el = new TiXmlElement(val.c_str()); // What about this object ptr?
TiXmlText * txt = new TiXmlText(node.GetNodeValue().c_str()); // And this one?
el->LinkEndChild(txt);
document.LinkEndChild(el);
}
答案 0 :(得分:6)
通常,您需要在两个指针上调用delete
以避免内存泄漏。但在你的情况下,看起来你把这个指针放在document
对象中(我假设document
存储了指针本身并且不会创建 copy <指向对象本身的/ em>。因此,如果您在此处调用delete
,则您为document
对象指定的指针将无效。因此,如果document
对象拥有删除您在此函数中分配的内存的所有权,那么您不应在此处调用delete
,否则如果它正在创建您传递的对象的副本,那么您需要{ {1}}在这里。在这些类型的场景中,使用智能指针非常有用。有关详细信息,请查看boost::shared_ptr。
答案 1 :(得分:1)
使用new时,会分配堆中的内存,而在函数中本地声明的对象将在堆栈中分配。
分配给堆栈的对象在方法调用后停止存在
在您的情况下,TiXmlElement* el
是在堆栈上分配的指针,它引用堆上的内存。离开函数后,el
指针将停止存在(因为它在堆栈上),但它引用的内存仍然存在(在堆上)。因此,如果该内存未被“释放”,则被视为“泄露”
答案 2 :(得分:1)
唯一可以肯定的是,在此函数退出后,这些指针都没有返回到堆中。
函数退出后会发生什么情况取决于将指针传递到LinkEndChild
所暗示的内存使用量合约。在此之后您是否仍然拥有内存,或者在新的父级(在这种情况下为document
,直接访问el
的内存,并通过el
for { {1}})被清理干净了吗?如果是前者,那么你是不正确的txt
它。如果是后者,那么在某些时候你需要清理它,大概是在完成delete
(全局?类成员?)之后。
另一个细微差别是构建document
和TiXmlElement
的合同是什么 - 它们是复制输入C字符串还是通过引用使用它们?
我猜这是TiXmlText
的文档来清理链接到文档中的所有内存。但是有点凌乱。检查析构函数XmlDocument
,查看它是否列出了清理它们的子列表(递归)。
编辑:这看起来像TinyXML,在这种情况下它应该清理你在销毁时给它的所有内存。请参阅此处进行讨论:http://www.gamedev.net/community/forums/topic.asp?topic_id=518023
TinyXML的语义显然意味着 (a)它拥有文件树, (b)你传入你的节点 分配。我看不出好的论点 因为它不是简单地使用删除 运营商与其相关的一切。
编辑:事实上,鉴于TinyXML(或 至少我在这里的副本清楚 我猜测,在TiXMLNode析构函数中有XmlDocument::~XlmDocument
这只是TinyXML ++中的一个错误 包装
另请参阅有关TinyXml内存管理的先前Stack Overflow问题here。
documentation for LinkEndChild 这样说:
注意:要添加的节点已通过 通过指针,将来会如此 由tinyXml拥有(和删除)。这个 方法是有效的,避免了 额外的副本,但应该使用 因为它使用不同的记忆 模型比其他插入函数。