gpt4 book ai didi

c++ - libxml 2 的 xml 复制 NodeList 中的内存泄漏

转载 作者:行者123 更新时间:2023-11-30 19:46:25 24 4
gpt4 key购买 nike

我在使用 libxml2 时遇到问题。

我正在尝试复制节点列表并将其保存到文件中。代码构建并运行,但当我在 valgrind 中运行它时出现错误。

这是我的测试代码:test_libxml.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libxml/parser.h>
#include <libxml/tree.h>

#define RSS_XML "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"\
"<rss version=\"2.0\">\n"\
"\t<channel>\n"\
"\t\t<item>\n"\
"\t\t\t<title>Some Title</title>\n"\
"\t\t\t<description>Some Description</description>\n"\
"\t\t</item>\n\t\t<item>\n"\
"\t\t\t<title>Another Title</title>\n"\
"\t\t\t<description>Another Description</description>\n"\
"\t\t</item>\n"\
"\t</channel>\n"\
"</rss>\n"


static const char document [] = RSS_XML;

static int parse_rss (const char *content, int content_len);
static void parse_channel (xmlNodePtr channel);
static void save_item (xmlNodePtr item);

int main (int argc, char *argv[])
{
int ret = 1;

xmlInitParser ();

ret = parse_rss (document, sizeof (document) - 1);

xmlCleanupParser();
xmlMemoryDump();

return ret;
}

static int parse_rss (const char *content, int content_len)
{
xmlParserCtxtPtr parser;
xmlDocPtr doc;

parser = xmlNewParserCtxt ();
if (parser == NULL) {
fprintf (stderr, "Failed to creste parser\n");
return 1;
}


doc = xmlCtxtReadMemory (parser, content, content_len, NULL, NULL, 0);
if (doc == NULL) {
xmlFreeParserCtxt (parser);
fprintf (stderr, "Failed to parse document\n");
return 1;
}


xmlNodePtr root = xmlDocGetRootElement (doc);
xmlNodePtr node = root->children;

while (node) {
if (node->type == XML_ELEMENT_NODE
&& xmlStrEqual (node->name, BAD_CAST "channel"))
{
parse_channel (node);
}

node = node->next;
}

xmlFreeDoc (doc);
xmlFreeParserCtxt (parser);

return 0;
}

static void parse_channel (xmlNodePtr channel)
{
xmlNodePtr node = channel->children;

while (node) {
if (node->type == XML_ELEMENT_NODE
&& xmlStrEqual (node->name, BAD_CAST "item"))
{
save_item (node);
}

node = node->next;
}
}

static void save_item (xmlNodePtr item)
{
static int i = 0;
char filename [200];

sprintf (filename, "item_%d.xml", i++);

xmlDocPtr doc = xmlNewDoc (NULL);
if (doc == NULL) {
return;
}

xmlNodePtr temp = xmlCopyNodeList (item);
if (temp == NULL) {
xmlFreeDoc (doc);
return;
}

xmlDocSetRootElement (doc, temp);

xmlSaveFile (filename, doc);

xmlUnlinkNode (temp);
xmlFreeNodeList (temp);
xmlFreeDoc (doc);
}

这是 valgrind 输出:

==6581== Memcheck, a memory error detector
==6581== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==6581== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==6581== Command: ./build/test_libxml
==6581==
==6581==
==6581== HEAP SUMMARY:
==6581== in use at exit: 741 bytes in 22 blocks
==6581== total heap usage: 145 allocs, 123 frees, 26,427 bytes allocated
==6581==
==6581== 741 (120 direct, 621 indirect) bytes in 2 blocks are definitely lost in loss record 9 of 9
==6581== at 0x4006ADD: malloc (vg_replace_malloc.c:291)
==6581== by 0x8076696: xmlStaticCopyNode (in test_libxml)
==6581== by 0x8076B70: xmlStaticCopyNodeList (in test_libxml)
==6581== by 0x8076C71: xmlCopyNodeList (in test_libxml)
==6581== by 0x8049925: save_item (test_libxml.c:107)
==6581== by 0x80498C2: parse_channel (test_libxml.c:88)
==6581== by 0x804984F: parse_rss (test_libxml.c:68)
==6581== by 0x8049734: main (test_libxml.c:33)
==6581==
==6581== LEAK SUMMARY:
==6581== definitely lost: 120 bytes in 2 blocks
==6581== indirectly lost: 621 bytes in 20 blocks
==6581== possibly lost: 0 bytes in 0 blocks
==6581== still reachable: 0 bytes in 0 blocks
==6581== suppressed: 0 bytes in 0 blocks
==6581==
==6581== For counts of detected and suppressed errors, rerun with: -v
==6581== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 14 from 8)

libxml2版本是2.9.1

感谢任何帮助。谢谢

最佳答案

正如@nwellnhof提到的

正确使用的函数确实是 xmlCopyNode。

这是正确的代码

static void save_item (xmlNodePtr item)
{
static int i = 0;
char filename [200];

sprintf (filename, "item_%d.xml", i++);

xmlDocPtr doc = xmlNewDoc (NULL);
if (doc == NULL) {
return;
}

xmlNodePtr temp = xmlCopyNode(item, 1);
if (temp == NULL) {
xmlFreeDoc (doc);
return;
}

xmlDocSetRootElement (doc, temp);

xmlSaveFile (filename, doc);

xmlFreeDoc (doc);
}

关于c++ - libxml 2 的 xml 复制 NodeList 中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23935861/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com