Утечка памяти после возврата xmlChar из функции


Поэтому я решил написать свою первую продвинутую программу на языке Си, после долгих отладок и исправлений мне удалось заставить ее работать. Он компилирует и выполняет должным образом возврат ожидаемых результатов(за исключением того, что функция find всегда возвращает 0 по какой-то причине). Однако, когда я запустил valgrid на нем, я получил много утечек памяти, поэтому после нескольких часов почесывания головы я понятия не имел, где эти утечки. Вот код:

Код:

#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 %sn", 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 -> %sn", 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.xmln");
        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 %sn", 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("%dn", cont[0] == NULL);
    printResults();

    freeCont();
    xmlFree(root);
    xmlFree(doc);
    xmlCleanupParser();

    return 0;
}

И вальгринд доклад:

Выход Valgrind:

==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)

Я попробовал валгринда с --leak-check=full, но отчет был длинным и слишком сложным для меня. Он упомянул в длинном отчете что-то о функции getName, но я не вижу в этом никакой проблемы!

Где эти утечки?

Редактировать:

Запустил valgrind после добавления free(cont) в конце функции freeCont, Вот отчет с -- leak-check=full flag:

Valgrind -- проверка утечки=full-v ./XML данные.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)
2 2

2 ответа:

Вы неправильно используете API libxml.

1) Вызов xmlFree(doc) просто освобождает память, используемую узлом документа; он не очищает все дерево документов. Вместо этого сделайте xmlFreeDoc(doc);.

2) Не пытайтесь освободить узлы, принадлежащие документу. Вызов xmlFree(root); не разрешен, так как корневой узел принадлежит документу, а не вам. Аналогично для узла, который вы собираете в find. Также нет причин дублировать строки. Они являются частью документа, и вы можете содержать ссылки на них. их до тех пор, пока документ действителен.

Вы никогда не освобождаете cont, то есть фактический массив.

Это распределение:

cont = calloc(MAX, sizeof(struct child*));

Не уравновешивается вызовом

free(cont);

Перед завершением работы программы. Тем не менее, это редко мудрая идея, чтобы использовать глобальные переменные, как это.