指向功能范围内的对象

时间:2010-10-20 13:56:08

标签: c++ pointers function

当你在函数范围内创建一些指针时,当函数超出范围时会发生什么?它们会被销毁吗?或者我应该在某些时候对它们进行删除?

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);
}

3 个答案:

答案 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(全局?类成员?)之后。

另一个细微差别是构建documentTiXmlElement的合同是什么 - 它们是复制输入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拥有(和删除)。这个   方法是有效的,避免了   额外的副本,但应该使用   因为它使用不同的记忆   模型比其他插入函数。