So i decided to write my first advanced C program, after long debuging and fixing i managed to get it to work. It compiles and executes properly an return the expected results(except that the find
function always return 0 for some reason). However when i ran valgrid on it i got lots of memory leaks, so after head scratching for few hours i had no clue where r those leaks. Here's the code:
Code:
#include <libxml2/libxml/parser.h>
#include <libxml2/libxml/tree.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 10
xmlDoc *doc;
xmlNode *root;
struct child {
const xmlChar *grandfather;
const xmlChar *father;
const xmlChar *name;
xmlNode *node;
};
struct child **cont;
const xmlChar *getName(xmlNode *node) {
xmlNode *cur;
for (cur = node->children; cur != NULL; cur = cur->next) {
if (!xmlStrcmp(cur->name, (const xmlChar *) "name"))
return xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
}
return (const xmlChar *) "none";
}
void printResults() {
int i = 0;
while (cont[i] != NULL) {
printf("%d- %s son of %s son of %s\n", i + 1,
cont[i]->name, cont[i]->father, cont[i]->grandfather);
i++;
}
}
void freeCont() {
int i = 0;
while (cont[i] != NULL) {
xmlFree((xmlChar *) cont[i]->father);
xmlFree((xmlChar *) cont[i]->grandfather);
xmlFree((xmlChar *) cont[i]->name);
xmlFree(cont[i]->node);
i++;
}
}
int find(xmlNode *node, const xmlChar *key, const xmlChar *grandfather, const xmlChar *father) {
int i = 0;
const xmlChar *name;
xmlNode *cur;
for (cur = node; cur != NULL && i < MAX; cur = cur->next) {
if (cur->type == XML_ELEMENT_NODE) {
if (!xmlStrcmp(cur->name, (const xmlChar *) "child")) {
name = xmlStrdup(getName(cur));
printf("%s -> %s -> %s\n", grandfather, father, name);
if (!xmlStrcmp(name, key)) {
cont[i] = malloc(sizeof(struct child));
cont[i]->grandfather = xmlStrdup(grandfather);
cont[i]->father = xmlStrdup(father);
cont[i]->name = xmlStrdup(name);
cont[i]->node = cur;
printf("found something....\n");
i++;
}
if (cur->children) find(cur->children, key, name, father);
xmlFree((xmlChar *) name);
}
else if (cur->children)
find(cur->children, key, father, grandfather);
}
}
return i == 0 ? 0 : 1;
}
int main(int argc, char *argv[])
{
if (argc < 2) {
printf("Usage: xml filename.xml\n");
return 1;
}
LIBXML_TEST_VERSION
cont = calloc(MAX, sizeof(struct child*));
int rv = 0;
if ((doc = xmlReadFile(argv[1], NULL, 0)) == NULL) {
printf("error: could not parse file %s\n", argv[1]);
exit(-1);
}
root = xmlDocGetRootElement(doc);
if ((rv = find(root, (xmlChar *) "Peter", (const xmlChar *) "none", (const xmlChar *) "none")) == 1)
printResults();
else printf("(%d)Nothing found!\n", sizeof cont / sizeof cont[0]);
printf("%d\n", cont[0] == NULL);
printResults();
freeCont();
xmlFree(root);
xmlFree(doc);
xmlCleanupParser();
return 0;
}
and the valgrind report:
Valgrind output:
==16316== Memcheck, a memory error detector
==16316== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==16316== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==16316== Command: ./xml data.xml
==16316==
none -> none -> Mike
none -> Mike -> James
Mike -> James -> John
Mike -> James -> Thomas
Mike -> James -> William
Mike -> James -> Daniel
Mike -> James -> Peter
found something....
none -> Mike -> Charlie
none -> Mike -> George
none -> Mike -> Lewis
none -> Mike -> Luke
(1)Nothing found!
0
1- Peter son of James son of Mike
==16316==
==16316== HEAP SUMMARY:
==16316== in use at exit: 22,769 bytes in 362 blocks
==16316== total heap usage: 434 allocs, 72 frees, 65,527 bytes allocated
==16316==
==16316== LEAK SUMMARY:
==16316== definitely lost: 293 bytes in 17 blocks
==16316== indirectly lost: 22,420 bytes in 343 blocks
==16316== possibly lost: 0 bytes in 0 blocks
==16316== still reachable: 56 bytes in 2 blocks
==16316== suppressed: 0 bytes in 0 blocks
==16316== Rerun with --leak-check=full to see details of leaked memory
==16316==
==16316== For counts of detected and suppressed errors, rerun with: -v
==16316== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
I tried valgrind with --leak-check=full
but the report was long and too complicated for me. It mentioned in the long report something about the getName
function but i don't see any problem with it!
Where are those leaks?
Edit:
ran valgrind after adding free(cont)
at the end of freeCont
function, here's the report with --leak-check=full flag:
valgrind --leak-check=full -v ./xml data.xml:
==16843== Memcheck, a memory error detector
==16843== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==16843== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==16843== Command: ./xml data.xml
==16843==
--16843-- Valgrind options:
--16843-- --leak-check=full
--16843-- -v
--16843-- Contents of /proc/version:
--16843-- Linux version 3.13.0-39-generic (buildd@roseapple) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #66-Ubuntu SMP Tue Oct 28 13:31:23 UTC 2014
--16843-- Arch and hwcaps: X86, x86-mmxext-sse1-sse2
--16843-- Page sizes: currently 4096, max supported 4096
--16843-- Valgrind library directory: /usr/lib/valgrind
--16843-- Reading syms from /lib/i386-linux-gnu/ld-2.19.so
--16843-- Considering /lib/i386-linux-gnu/ld-2.19.so ..
--16843-- .. CRC mismatch (computed 19686c0d wanted 131a893d)
--16843-- Considering /usr/lib/debug/lib/i386-linux-gnu/ld-2.19.so ..
--16843-- .. CRC is valid
--16843-- Reading syms from /home/arcm/Projects/c/xml/xml
--16843-- Reading syms from /usr/lib/valgrind/memcheck-x86-linux
--16843-- Considering /usr/lib/valgrind/memcheck-x86-linux ..
--16843-- .. CRC mismatch (computed e09cad6a wanted c3463efc)
--16843-- object doesn't have a symbol table
--16843-- object doesn't have a dynamic symbol table
--16843-- Scheduler: using generic scheduler lock implementation.
--16843-- Reading suppressions file: /usr/lib/valgrind/default.supp
==16843== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-16843-by-arcm-on-???
==16843== embedded gdbserver: writing to /tmp/vgdb-pipe-to-vgdb-from-16843-by-arcm-on-???
==16843== embedded gdbserver: shared mem /tmp/vgdb-pipe-shared-mem-vgdb-16843-by-arcm-on-???
==16843==
==16843== TO CONTROL THIS PROCESS USING vgdb (which you probably
==16843== don't want to do, unless you know exactly what you're doing,
==16843== or are doing some strange experiment):
==16843== /usr/lib/valgrind/../../bin/vgdb --pid=16843 ...command...
==16843==
==16843== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==16843== /path/to/gdb ./xml
==16843== and then give GDB the following command
==16843== target remote | /usr/lib/valgrind/../../bin/vgdb --pid=16843
==16843== --pid is optional if only one valgrind process is running
==16843==
--16843-- REDIR: 0x4017ed0 (strlen) redirected to 0x38066872 (???)
--16843-- REDIR: 0x4017ce0 (index) redirected to 0x3806684d (???)
--16843-- Reading syms from /usr/lib/valgrind/vgpreload_core-x86-linux.so
--16843-- Considering /usr/lib/valgrind/vgpreload_core-x86-linux.so ..
--16843-- .. CRC mismatch (computed da218fa9 wanted d8f40358)
--16843-- object doesn't have a symbol table
--16843-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so
--16843-- Considering /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so ..
--16843-- .. CRC mismatch (computed f1cf8ee0 wanted 71765c70)
--16843-- object doesn't have a symbol table
==16843== WARNING: new redirection conflicts with existing -- ignoring it
--16843-- old: 0x04017ed0 (strlen ) R-> (0000.0) 0x38066872 ???
--16843-- new: 0x04017ed0 (strlen ) R-> (2007.0) 0x0402d480 strlen
--16843-- Reading syms from /usr/lib/i386-linux-gnu/libxml2.so.2.9.1
--16843-- object doesn't have a symbol table
--16843-- Reading syms from /lib/i386-linux-gnu/libc-2.19.so
--16843-- Considering /lib/i386-linux-gnu/libc-2.19.so ..
--16843-- .. CRC mismatch (computed 937a2085 wanted ec4e4880)
--16843-- Considering /usr/lib/debug/lib/i386-linux-gnu/libc-2.19.so ..
--16843-- .. CRC is valid
--16843-- Reading syms from /lib/i386-linux-gnu/libdl-2.19.so
--16843-- Considering /lib/i386-linux-gnu/libdl-2.19.so ..
--16843-- .. CRC mismatch (computed 1fc0f587 wanted 1b016046)
--16843-- Considering /usr/lib/debug/lib/i386-linux-gnu/libdl-2.19.so ..
--16843-- .. CRC is valid
--16843-- Reading syms from /lib/i386-linux-gnu/libz.so.1.2.8
--16843-- object doesn't have a symbol table
--16843-- Reading syms from /lib/i386-linux-gnu/liblzma.so.5.0.0
--16843-- object doesn't have a symbol table
--16843-- Reading syms from /lib/i386-linux-gnu/libm-2.19.so
--16843-- Considering /lib/i386-linux-gnu/libm-2.19.so ..
--16843-- .. CRC mismatch (computed 65e47b8b wanted 582b65c1)
--16843-- Considering /usr/lib/debug/lib/i386-linux-gnu/libm-2.19.so ..
--16843-- .. CRC is valid
--16843-- REDIR: 0x4237670 (strnlen) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x4239620 (strncasecmp) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x423efa0 (memrchr) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x4251fe0 (wcslen) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x4236e10 (strcmp) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x4239030 (memmove) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x4239780 (memcpy) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x4238d00 (bcmp) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x42393d0 (stpcpy) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x42369f0 (strcat) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x4236ee0 (strcpy) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x42b62e0 (__memmove_chk) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x42b6290 (__memcpy_chk) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x4236c00 (index) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x4237560 (strlen) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x42390f0 (memset) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x4238b10 (memchr) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x4237770 (strncpy) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x4237710 (strncmp) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--16843-- REDIR: 0x4237820 (__GI_strrchr) redirected to 0x402ce50 (__GI_strrchr)
--16843-- REDIR: 0x4232f40 (malloc) redirected to 0x402a110 (malloc)
--16843-- REDIR: 0x42375b0 (__GI_strlen) redirected to 0x402d400 (__GI_strlen)
--16843-- REDIR: 0x423f600 (__GI_strncmp) redirected to 0x402dc60 (__GI_strncmp)
--16843-- REDIR: 0x42e9dd0 (__memcpy_ssse3) redirected to 0x402eda0 (memcpy)
--16843-- REDIR: 0x4233860 (calloc) redirected to 0x402c090 (calloc)
--16843-- REDIR: 0x423f700 (__strlen_sse2_bsf) redirected to 0x402d3e0 (strlen)
--16843-- REDIR: 0x423f8c0 (__strcpy_ssse3) redirected to 0x402d4c0 (strcpy)
--16843-- REDIR: 0x4241110 (__strncpy_ssse3) redirected to 0x402d680 (strncpy)
--16843-- REDIR: 0x42334f0 (free) redirected to 0x402b370 (free)
--16843-- REDIR: 0x4300610 (__memcmp_ssse3) redirected to 0x4030080 (bcmp)
--16843-- REDIR: 0x42f7820 (__strncmp_ssse3) redirected to 0x402dbc0 (strncmp)
--16843-- REDIR: 0x42335a0 (realloc) redirected to 0x402c2b0 (realloc)
--16843-- REDIR: 0x42eddb0 (__memmove_ssse3) redirected to 0x40308b0 (memmove)
--16843-- REDIR: 0x423b560 (strchrnul) redirected to 0x4030e50 (strchrnul)
none -> none -> Mike
none -> Mike -> James
Mike -> James -> John
Mike -> James -> Thomas
Mike -> James -> William
Mike -> James -> Daniel
Mike -> James -> Peter
found something....
none -> Mike -> Charlie
none -> Mike -> George
none -> Mike -> Lewis
none -> Mike -> Luke
(1)Nothing found!
0
1- Peter son of James son of Mike
==16843==
==16843== HEAP SUMMARY:
==16843== in use at exit: 22,729 bytes in 361 blocks
==16843== total heap usage: 434 allocs, 73 frees, 65,527 bytes allocated
==16843==
==16843== Searching for pointers to 361 not-freed blocks
==16843== Checked 85,888 bytes
==16843==
==16843== 4 bytes in 1 blocks are definitely lost in loss record 1 of 27
==16843== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==16843== by 0x4100C84: xmlStrndup (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x4100D0D: xmlStrdup (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x40A52F6: xmlNewDoc (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x415461A: xmlSAX2StartDocument (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409DF77: xmlParseDocument (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409E19F: ??? (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x8048C55: main (xml.c:130)
==16843==
==16843== 5 bytes in 1 blocks are definitely lost in loss record 2 of 27
==16843== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==16843== by 0x4100C84: xmlStrndup (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x4100D0D: xmlStrdup (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x40A559E: xmlNodeListGetString (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x80488DB: getName (xml.c:31)
==16843== by 0x8048A74: find (xml.c:92)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048CBE: main (xml.c:139)
==16843==
==16843== 9 bytes in 1 blocks are definitely lost in loss record 3 of 27
==16843== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==16843== by 0x4100C84: xmlStrndup (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x4100D0D: xmlStrdup (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x40BAB17: xmlPathToURI (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x41546B5: xmlSAX2StartDocument (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409DF77: xmlParseDocument (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409E19F: ??? (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x8048C55: main (xml.c:130)
==16843==
==16843== 16 bytes in 1 blocks are definitely lost in loss record 4 of 27
==16843== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==16843== by 0x8048AD4: find (xml.c:96)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048B7E: find (xml.c:105)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048B7E: find (xml.c:105)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048CBE: main (xml.c:139)
==16843==
==16843== 26 bytes in 5 blocks are definitely lost in loss record 7 of 27
==16843== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==16843== by 0x4100C84: xmlStrndup (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x4100D0D: xmlStrdup (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x40A559E: xmlNodeListGetString (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x80488DB: getName (xml.c:31)
==16843== by 0x8048A74: find (xml.c:92)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048B7E: find (xml.c:105)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048CBE: main (xml.c:139)
==16843==
==16843== 37 bytes in 5 blocks are definitely lost in loss record 9 of 27
==16843== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==16843== by 0x4100C84: xmlStrndup (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x4100D0D: xmlStrdup (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x40A559E: xmlNodeListGetString (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x80488DB: getName (xml.c:31)
==16843== by 0x8048A74: find (xml.c:92)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048B7E: find (xml.c:105)
==16843== by 0x8048BBA: find (xml.c:109)
==16843== by 0x8048BBA: find (xml.c:109)
==16843==
==16843== 92 (60 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 14 of 27
==16843== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==16843== by 0x40A57F0: xmlNewDocPI (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x415424E: xmlSAX2ProcessingInstruction (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x4094721: xmlParsePI (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409B027: xmlParseMisc (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409DC67: xmlParseDocument (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409E19F: ??? (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x8048C55: main (xml.c:130)
==16843==
==16843== 1,032 (60 direct, 972 indirect) bytes in 1 blocks are definitely lost in loss record 21 of 27
==16843== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==16843== by 0x4155C46: ??? (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x4156CC9: xmlSAX2Characters (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x4092F33: xmlParseCharData (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409CF01: xmlParseContent (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409D7C5: xmlParseElement (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409CFD7: xmlParseContent (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409D7C5: xmlParseElement (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409CFD7: xmlParseContent (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409D7C5: xmlParseElement (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409CFD7: xmlParseContent (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409D7C5: xmlParseElement (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843==
==16843== 3,676 (32 direct, 3,644 indirect) bytes in 1 blocks are definitely lost in loss record 23 of 27
==16843== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==16843== by 0x4152A96: xmlDictCreate (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x408780C: xmlInitParserCtxt (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x4087CE3: xmlNewParserCtxt (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409BD2E: xmlCreateURLParserCtxt (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x40A23EC: xmlReadFile (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x8048C55: main (xml.c:130)
==16843==
==16843== 17,832 (60 direct, 17,772 indirect) bytes in 1 blocks are definitely lost in loss record 27 of 27
==16843== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==16843== by 0x4155C46: ??? (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x4156CC9: xmlSAX2Characters (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x4092F33: xmlParseCharData (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409CF01: xmlParseContent (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409D7C5: xmlParseElement (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409DDB1: xmlParseDocument (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x409E19F: ??? (in /usr/lib/i386-linux-gnu/libxml2.so.2.9.1)
==16843== by 0x8048C55: main (xml.c:130)
==16843==
==16843== LEAK SUMMARY:
==16843== definitely lost: 309 bytes in 18 blocks
==16843== indirectly lost: 22,420 bytes in 343 blocks
==16843== possibly lost: 0 bytes in 0 blocks
==16843== still reachable: 0 bytes in 0 blocks
==16843== suppressed: 0 bytes in 0 blocks
==16843==
==16843== ERROR SUMMARY: 10 errors from 10 contexts (suppressed: 0 from 0)
==16843== ERROR SUMMARY: 10 errors from 10 contexts (suppressed: 0 from 0)
You aren't using the libxml API properly.
1) Calling xmlFree(doc)
simply frees the memory used by the document node; it does not clean up the entire document tree. Instead, do xmlFreeDoc(doc);
.
2) Don't attempt to free any nodes owned by the document. Calling xmlFree(root);
is not allowed since the root node is owned by the document, not you. Similar for the node you collect in find. There's also no reason to duplicate the strings. They are part of the document and you can hold references to them as long as the document is valid.