C++ 指向函数作用域中对象的指针

C++ 指向函数作用域中对象的指针,c++,pointers,function,C++,Pointers,Function,当您在函数的作用域内创建一些指针时,当函数超出作用域时会发生什么?它们是否会被销毁,或者我应该在某个时候调用delete void XMLDocument::AddNode(XMLNode& node) { std::string val = node.GetNodeName(); TiXmlElement* el = new TiXmlElement(val.c_str()); // What about this object ptr? TiXmlText

当您在函数的作用域内创建一些指针时,当函数超出作用域时会发生什么?它们是否会被销毁,或者我应该在某个时候调用delete

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

通常,您需要在两个指针上调用
delete
,以避免内存泄漏。但在您的情况下,看起来您将此指针放在
文档
对象中(我假设
文档
存储指针本身,并且不会创建指向对象本身的副本)。因此,如果您在此处调用
delete
,则指定给
文档
对象的指针将无效。因此,如果
document
对象拥有删除您在此函数中分配的内存的所有权,那么您不应该在此处调用
delete
,否则如果它正在创建您传递的对象的副本,那么您需要在此处删除它。在这种情况下,使用智能指针将非常有用。查看更多详细信息。

使用new时,会从堆中分配内存,而在函数中本地声明的对象会在堆栈中分配。
分配给堆栈的对象在方法调用后停止存在。

在您的例子中,
tixmlement*el
是在堆栈上分配的指针,它引用堆上的内存。离开函数后,
el
指针将停止存在(因为它在堆栈上),但它引用的内存仍然存在(在堆上)。因此,如果该内存没有“释放”,则被视为“泄漏”

唯一可以确定的是,在该函数退出后,这些指针都没有返回到堆中

函数退出后发生的情况取决于内存使用的约定,该约定是通过将指针传递到
LinkEndChild
中而隐含的。在此之后,您是否仍然拥有内存,或者在清理新的父级(在本例中为
document
,它直接访问
el
,并通过
el
访问
txt
)时,内存是否已被清理?如果是前者,则不删除它是正确的。如果是后者,那么在某个时候您需要清理它,大概是在
文档
(全局?类成员?)完成之后

另一个细微差别是关于构建
tixmlement
TiXmlText
的合同是什么-他们是复制输入的C字符串,还是通过引用使用它们

我猜是
XmlDocument
的文档清除了链接到文档中的所有内存。不过有点乱。检查析构函数
XmlDocument::~XlmDocument
,看看它是否会带着一列子对象(递归地)清理它们

编辑:这看起来像TinyXML,在这种情况下,它应该在销毁时清除您提供给它的所有内存。有关讨论,请参见此处:

TinyXML的语义清楚地暗示 (a)它拥有文档树, 和(b)您传入您需要的节点 分配我看不出有什么好论点 对于它,不只是使用delete 连接到它的所有东西的操作员

编辑:事实上,考虑到TinyXML(或 至少我这里的副本)清楚 当(节点){temp=node;节点 =node->next;delete temp;}在TiXMLNode析构函数中,我猜 这只是TinyXML中的一个bug++ 包装纸

另请参阅前面关于TinyXml内存管理的堆栈溢出问题

他说:

注意:要添加的节点已传递 通过指针,并将从此 由tinyXml拥有(并删除)。这 该方法是有效的,避免了错误 额外副本,但应与 小心,因为它使用不同的内存 模型,而不是其他插入函数


使用智能指针<代码>这是一个一般性问题,还是特定于
TinyXml
用法?正确的答案取决于此。不要这样认为,我认为op是在询问使用new创建的对象的指针