rug-compling / alpinocorpus

Library for handling Alpino corpora
GNU Lesser General Public License v2.1
8 stars 1 forks source link

lek in iterator #31

Closed pebbe closed 10 years ago

pebbe commented 10 years ago

Ik heb een C-programmaatje dat alle entries (naam en inhoud) uit een stel dact-bestanden leest. Het geheugengebruik blijft daarbij constant groeien. Na verwerking van bijna 100000 entries (in tien dact-bestanden) geeft top dit aan (op machine urd):

  PID USER      VIRT  RES  SHR SWAP %MEM %CPU   TIME COMMAND
23667 alfa      794m 704m  10m  89m 35.0   20   1:08 dctest

Hier is het programmaatje:

#include <stdio.h>
#include <AlpinoCorpus/capi.h>

int main (int argc, char *argv [])
{
    int
        i;
    long
        count = 0;
    alpinocorpus_reader
        r;
    alpinocorpus_iter
        it;
    alpinocorpus_entry
        ent;

    alpinocorpus_initialize();
    for (i = 1; i < argc; i++) {
        r = alpinocorpus_open(argv[i]);
        it = alpinocorpus_entry_iter(r);
        while (alpinocorpus_iter_has_next(r, it)) {
            ent = alpinocorpus_iter_next(r, it);
            printf("%li %s\n", ++count, alpinocorpus_entry_name(ent));
            alpinocorpus_entry_contents(ent);
            alpinocorpus_entry_free(ent);
        }
        alpinocorpus_close(r);
    }

    return 0;
}

Nog een bug: als ik bovenstaand programma de twee includes omwissel, dan krijg ik van de compiler een foutmelding:

In file included from dctest.c:1:
/my/opt/alpino/include/AlpinoCorpus/capi.h:63: error: expected declaration specifiers or ‘...’ before ‘size_t’
/my/opt/alpino/include/AlpinoCorpus/capi.h:127: error: expected declaration specifiers or ‘...’ before ‘size_t’
/my/opt/alpino/include/AlpinoCorpus/capi.h:146: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘alpinocorpus_size’
make: *** [dctest] Fout 1
danieldk commented 10 years ago

On Sep 26, 2013, at 1:39 AM, Peter Kleiweg wrote:

    r = alpinocorpus_open(argv[i]);
    it = alpinocorpus_entry_iter(r);
    while (alpinocorpus_iter_has_next(r, it)) {
        ent = alpinocorpus_iter_next(r, it);
        printf("%li %s\n", ++count, alpinocorpus_entry_name(ent));
        alpinocorpus_entry_contents(ent);
        alpinocorpus_entry_free(ent);
    }

Volgens mij mis je hier een:

alpinocorpus_iter_destroy(it);

Nog een bug: als ik bovenstaand programma de twee includes omwissel, dan krijg ik van de compiler een foutmelding:

In file included from dctest.c:1: /my/opt/alpino/include/AlpinoCorpus/capi.h:63: error: expected declaration specifiers or ‘...’ before ‘size_t’ /my/opt/alpino/include/AlpinoCorpus/capi.h:127: error: expected declaration specifiers or ‘...’ before ‘size_t’ /my/opt/alpino/include/AlpinoCorpus/capi.h:146: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘attribute’ before ‘alpinocorpus_size’ make: *\ [dctest] Fout 1

Daar miste inderdaad een include. Bedankt!

danieldk commented 10 years ago

Ik heb je programma nog even geprobeerd, en als ik alpinocorpus_iter_destroy(it) toevoeg krijg ik geen lek. Dus het is waarschijnlijk een foutje in je programma.

pebbe commented 10 years ago

Ik hou een lek, maar het zit ergens anders. Het programmaatje wat ik eerst gaf geeft niet precies de situatie aan. Ik gebruik alpinocorpus vanuit Go. Hier is de C-versie die precies hetzelfde doet:

#include <stdlib.h>
#include <stdio.h>
#include <AlpinoCorpus/capi.h>

int main (int argc, char *argv [])
{
    int
        i;
    long
        count = 0;
    char const
        *name;
    char
        *content;
    alpinocorpus_reader
        r;
    alpinocorpus_iter
        it;
    alpinocorpus_entry
        ent;

    alpinocorpus_initialize();
    for (i = 1; i < argc; i++) {
        r = alpinocorpus_open(argv[i]);
        it = alpinocorpus_entry_iter(r);
        while (alpinocorpus_iter_has_next(r, it)) {
            ent = alpinocorpus_iter_next(r, it);
            name = alpinocorpus_entry_name(ent);
            content = alpinocorpus_read(r, name);
            printf("%li %s\n", ++count, name);
            alpinocorpus_entry_free(ent);
            /* free(content); */
        }
        alpinocorpus_iter_destroy(it);
        alpinocorpus_close(r);
    }

    return 0;
}

Als ik een free toevoeg, dan verdwijnt het lek. Is dat de bedoeling? Ik kan niks in de C-api vinden dat zegt dat ik dit moet doen. Misschien handig om in de C-api bij elk geval waar de gebruiker een free moet gebruiken dat te melden.

danieldk commented 10 years ago

Als ik een free toevoeg, dan verdwijnt het lek. Is dat de bedoeling?

Ja. Ik zal het even aan de documentatie toevoegen. Overigens, als je toch aan het itereren bent, is het efficiënter _alpinocorpus_entrycontents te gebruiken.

pebbe commented 10 years ago

In alpinocorpus-go gebruik ik de C-functies hieronder die allemaal een string retourneren. Moet ik die bij al deze functies een free gebruiken?

alpinocorpus_write
alpinocorpus_write_corpus
alpinocorpus_entry_name
alpinocorpus_entry_contents
alpinocorpus_read
alpinocorpus_read_mark_query

Over _alpinocorpus_entrycontents: die geeft (gaf) vaak een leeg resultaat, tenzij de iterator was aangemaakt met _alpinocorpus_query_stylesheet_markeriter of _alpinocorpus_query_stylesheetiter. Is dat niet meer zo?

danieldk commented 10 years ago

On Sep 26, 2013, at 12:10 PM, Peter Kleiweg wrote:

In alpinocorpus-go gebruik ik de C-functies hieronder die allemaal een string retourneren. Moet ik die bij al deze functies een free gebruiken?

alpinocorpus_write alpinocorpus_write_corpus alpinocorpus_entry_name alpinocorpus_entry_contents alpinocorpus_read alpinocorpus_read_mark_query

De documentatie is nu bijgewerkt.

Over alpinocorpus_entry_contents: die geeft (gaf) vaak een leeg resultaat, tenzij de iterator was aangemaakt met alpinocorpus_query_stylesheet_marker_iter of alpinocorpus_query_stylesheet_iter. Is dat niet meer zo?

Je hebt gelijk. Als je een query geeft is het in principe leeg, tenzij de query bijvoorbeeld een attribuut evalueert. Het is heel erg lang geleden dat ik de API gebruikt heb ;).

pebbe commented 10 years ago

Ik zag dat capi.c is veranderd. Zou je de nieuwe versie kunnen installeren bij Letteren, of kun je daar niet meer inloggen?

danieldk commented 10 years ago

On Sep 26, 2013, at 1:07 PM, Peter Kleiweg wrote:

Ik zag dat capi.c is veranderd. Zou je de nieuwe versie kunnen installeren bij Letteren, of kun je daar niet meer inloggen?

Ik kan er nog inloggen, maar er zijn recent wat dingen veranderd in alpinocorpus, Dact en de Python plugin. Dus ik wil alles in één keer vernieuwen en controleren of het nog werkt. Wordt waarschijnlijk vanavond of morgen.

danieldk commented 10 years ago

On Sep 26, 2013, at 3:09 PM, Daniël de Kok wrote:

On Sep 26, 2013, at 1:07 PM, Peter Kleiweg wrote:

Ik zag dat capi.c is veranderd. Zou je de nieuwe versie kunnen installeren bij Letteren, of kun je daar niet meer inloggen?

Ik kan er nog inloggen, maar er zijn recent wat dingen veranderd in alpinocorpus, Dact en de Python plugin. Dus ik wil alles in één keer vernieuwen en controleren of het nog werkt. Wordt waarschijnlijk vanavond of morgen.

alpinocorpus is weer up-to-date.