关于tinyxml中new出对象却不delete是否存在内存泄露问题

版权声明:所有版权归作者她的吻让他,转载请标明出处. https://blog.csdn.net/qq_37059136/article/details/81663344

最近使用tinyxml操作xml文件,在操作中老是看到new一个对象但是并没有delete他,作为一个C++工作者,看着很是别扭,也心存疑惑:不delete难道不会内存泄露吗?经过我上网查询,发现有很多种说法,其中一种是tinyxml将所有对象都视为doc对象的子对象(TiXmlDocument对象就是这棵树的根结点, 在一个完整的文档中, 除了它, 其余结点必须都是它的后代, 所以TinyXml用了一个很巧妙的方法来析构每一个结点所对应的对象 ---- 每个结点的析构任务都委托给了它的父亲, 这样只要保证父亲被正确析构, 或者调用了父亲的Clear函数, 它的所有后代都会被正确的析构, 所以对整个文档来说只要TiXmlDocument对象被正确析构即可。)为此我专门写了程序证实这一点,下面是我的程序

#include "E:\\vs文档\\tinyxml静态库\\tinyxml静态库\\tinyxml.h"
#include "E:\\vs文档\\tinyxml静态库\\tinyxml静态库\\tinystr.h"
#include <iostream>
#include <tchar.h>

#pragma comment(lib,"E:\\vs文档\\tinyxml静态库\\debug\\tinyxml静态库.lib")

using namespace std;
#define false 1
#define true  0

//创建xml文件
bool CreateSaveXml(string xmlfile)
{
    TiXmlDocument * pDoc = new TiXmlDocument;  //xml文档对象
	if(NULL == pDoc)
	{
		return false;
	}
    //生成Xml声明
	TiXmlDeclaration * pDeclaration = new TiXmlDeclaration("v0.0.0.1","ANSI","");//xml打头的文本申明
	if(NULL == pDeclaration)
	{
		return false;
	}
	pDoc->LinkEndChild(pDeclaration);




	//生成一个根节点 MyFirstXml
	TiXmlElement * pRoot = new TiXmlElement("MyFirstXml");
	if(NULL == pRoot)
	{
		return false;
	}
    pDoc->LinkEndChild(pRoot);
	pRoot->SetAttribute("version","v0.0.0.1");


	//生成第一个根节点的子节点 Message
	TiXmlElement * pRFChild = new TiXmlElement("Message");
	if(NULL == pRFChild)
	{
		return false;
	}
	pRoot->LinkEndChild(pRFChild);

	//生成Message的第一个子节点Hello
	TiXmlElement * pMFChild = new TiXmlElement("Hello");
	if(NULL == pMFChild)
	{
		return false;
	}
	pRFChild->LinkEndChild(pMFChild);

	//设置Hello节点的值
	string HelloValue = "Welcome to my first xml";
    TiXmlText * pHelloValue = new TiXmlText(HelloValue.c_str());
	pMFChild->LinkEndChild(pHelloValue);

	
    
	//生成Message的第二个子节点Congratulations
    TiXmlElement *pMSChild = new TiXmlElement("Congratulations");
	if(NULL == pMSChild)
	{
		return false;
	}
    pRFChild->LinkEndChild(pMSChild);

	//设置Congratulations节点的值
    string CongratulationsValue = "Congratulations on you!";
	TiXmlText *pCongratulationsValue = new TiXmlText(CongratulationsValue.c_str());
	pMSChild->LinkEndChild(pCongratulationsValue);
    
    //生成第一个根节点的第二个子节点
	TiXmlElement *pSRoot = new TiXmlElement("Body");
	if(NULL == pSRoot)
	{
		return false;
	}
	pRoot->LinkEndChild(pSRoot);

	//生成Body的第一个子节点
	TiXmlElement *pBFChild = new TiXmlElement("words");
	pSRoot->LinkEndChild(pBFChild);
    //设置节点的值
	string titlevalue = "every body woo~";
	TiXmlText *ptitlevalue = new TiXmlText(titlevalue.c_str());
	pBFChild->LinkEndChild(ptitlevalue);
   
	//生成body的第二个子节点
	TiXmlElement *pBSChild = new TiXmlElement("mainbody");
	pSRoot->LinkEndChild(pBSChild);
	pBSChild->SetAttribute("name","MainFrame");
	pBSChild->SetAttribute("x","5");
	/*pBSChild->SetAttribute(_T("y"),_T("15"));
	pBSChild->SetAttribute(_T("w"),_T("400"));
	pBSChild->SetAttribute(_T("h"),_T("250"));*/
    //设置节点的值
	string mainbodyvalue = "every body hands up~";
	TiXmlText *pmainbodyvalue = new TiXmlText(mainbodyvalue.c_str());
    pBSChild->LinkEndChild(pmainbodyvalue);

    


	pDoc->SaveFile(xmlfile.c_str());  //保存xml文档
	delete pDoc;  //这里是关键
	return true;

}

int main()
{
	string xmlfile = "E:\\a.xml";
    if(CreateSaveXml(xmlfile) == 0)
	{	
		cout << "Xml文档创建成功" << endl;
	}
	else
	{
        cout << "Xml文档创建失败" << endl;
	}
	cout << endl;

	////解析xml文档
 //   TiXmlDocument *pdoc = new TiXmlDocument;
	//pdoc->LoadFile("E:\\a.xml");
   
	//TiXmlElement *pFirstRoot = pdoc->FirstChildElement();
	//char * version = "v0.0.0.2";
	//if(strcmp(version,pFirstRoot->Attribute("version")))
	//{
	//	cout << "版本过旧,建议更新" << endl;
	//}
	////cout << pFirstRoot->Value() << endl;
	//cout << "当前版本: " << pFirstRoot->Attribute("version") << endl;

	//cout<< "最新版本: " << version << endl;

	//打印xml文档
	/*pdoc->Print();*/
    while (1)
    {
		CreateSaveXml(xmlfile);
    }
	return 0;
}

该程序做了一个非常简单的操作,就是创建一个简单的xml文档,为了检测内存泄露,我在主函数中写了一个死循环(一直创建xml文档,即一直new对象),下面我将进行两个测试:

①注释掉程序中的 delete pDoc;  //这里是关键 ,即不释放根节点

下面用内存泄露检测工具看一下内存泄露问题

截图手法不行,将就着看吧!我的进程是716xml.exe

②看一下释放根节点的内存泄露问题

这里的两者比较可以看出,只要释放了根节点,就不会出现内存泄露问题

由此可以得出结论:

则只要删除根节点,在程序中pDoc,就相当于把删除了TiXmlNode,相当于调用了TiXmlNode的析构函数。

猜你喜欢

转载自blog.csdn.net/qq_37059136/article/details/81663344