[xml] code error / memory leak ?



hi. I'm new to this mayling list. i have a small question about a strange effect I have seen using libxml2.

I wanted to copy some XML from a xmlDocPtr doc to another xmlDocPtr doc.
For exemple, having doc1 & doc2, i needed to copy a part of doc2 into doc1, then free doc2
so I tried this function :

--------------------------------
xmlCopyNodeList ()
xmlNodePtr  xmlCopyNodeList                 (const xmlNodePtr node);

Do a recursive copy of the node list.

node :  the first node in the list.
Returns :       a new xmlNodePtr, or NULL in case of error.
--------------------------------
But I was very surprised to have a big memory leak !! I loaded 200 times a file containing 40 ko of XML and it used around 60 Mo in RAM.
I searched and after several test i used :
--------------------------------
xmlCopyNode ()
xmlNodePtr  xmlCopyNode                     (const xmlNodePtr node,
                                            int recursive);

Do a copy of the node.

node :  the node
recursive :     if 1 do a recursive copy.
Returns :       a new xmlNodePtr, or NULL in case of error.
--------------------------------
I used this putting 1 in the `int recursive' field.

I don't know if I have made a mistake, or if the documentation don't tell everything, but this 2 function should have done the same work isn't it ?
The first one use 60 Mo of RAM the second one only few Ko.

i have read that normaly i must not post code, but i made a small example which will illustrate the problem :

---------------------------------
tmp.cpp
---------------------------------
#include <libxml/tree.h>
#include <libxml/parser.h>

int             main(int argc, char **argv)
{
 xmlDocPtr      main_doc;
 xmlNodePtr     main_root;
 int            cpt;

 // allocating main XML tree.
 main_doc = xmlNewDoc((const xmlChar*)"1.0");
 main_root = xmlNewDocNode(main_doc, NULL, (const xmlChar*)"root", NULL);
 xmlDocSetRootElement(main_doc, main_root);
 // copying small XML tree into main tree.
 for (cpt = 0; cpt < 200; cpt++)
   {
     xmlDocPtr          sub_doc;
     xmlNodePtr sub_root;
     xmlNodePtr cur;
     xmlNodePtr cpy;

     sub_doc = xmlParseFile("yop.xml");
     sub_root = xmlDocGetRootElement(sub_doc);
     for (cur = sub_root->xmlChildrenNode; cur != NULL; cur = cur->next)
        // cpy = xmlCopyNodeList(cur);          // this one do memory leak
        cpy = xmlDocCopyNode(cur, sub_doc, 1);  // this one is ok.
     xmlAddChild(main_root, cpy);
     xmlFreeDoc(sub_doc);
// debug :-/ ugly ... but useful ... for linux users (it shows the memory)
     system("ps -aux | grep \"./a.out\" | grep -v \"grep\"");
   }
 return (0);
}
-------------------------------
g++ tmp.cpp -lxml2

-------------------------------
"yop.xml"
-------------------------------
<?xml version="1.0"?>
<root>
 <Word>
   <is_empty>false</is_empty>
   <string>mot [1]</string>
   <root_string>mot racine</root_string>
   <type>Nom</type>
   <info>
     <value>info test</value>
   </info>
 </Word>
 <Word>
   <is_empty>false</is_empty>
   <string>mot [2]</string>
   <root_string>mot racine</root_string>
   <type>Nom</type>
   <info>
     <value>info test 2</value>
   </info>
 </Word>
</root>
-------------------------------

execution using xmlCopyNodeList :
first line of output : mdiablo 4905 0.0 0.2 3200 1248 pts/2 S 10:35 0:00 ./a.out last line of output : mdiablo 4905 1.0 0.5 5028 3048 pts/2 S 10:35 0:00 ./a.out

the memory 1248 -> 3048

execution using xmlDocCopyNode :
first line of output : mdiablo 5712 0.0 0.2 3200 1244 pts/2 S 10:36 0:00 ./a.out last line of output : mdiablo 5712 0.8 0.3 3756 1840 pts/2 S 10:36 0:00 ./a.out

the memory 1244 -> 1840 ( normal because data is added to the main_xml )

Thanks to have read this.

Marc.
--
http://mdiablo.homelinux.net

_________________________________________________________________
Trouvez l'âme soeur sur MSN Rencontres ! http://g.msn.fr/FR1000/9551




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]