C++ libxml2和x27中的内存泄漏;xmlCopyNodeList

C++ libxml2和x27中的内存泄漏;xmlCopyNodeList,c++,c,memory-leaks,libxml2,C++,C,Memory Leaks,Libxml2,我在使用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

我在使用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);
}
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);
}

我将问题代码转换为我的规范。编译并将其与SUSE Linux(SLES)上的gcc链接,没有错误或警告。无错误地执行程序(创建了两个文件)。在valgrind下执行:“./valgrind test”,其结果是:“错误摘要:0个上下文中的0个错误(抑制:4个上下文中的4个错误)”。libxml2-2.7.6。我的代码版本:有趣。我的环境是Centos 5.4如果使用
xmlCopyNode(项目1)
而不是
xmlCopyNodeList(项目)
,会发生什么?
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);
}