Memory Exhausted



  • Hi!

    Ich habe ein Programm entwickelt, welches die Boost Library benutzt, um reguläre Ausdrücke auszuwerten.

    In dem Bereich, in dem der Fehler auftritt, wird aus einem String, der den Quelltext einer HTML Seite enthält, mittels Capturing Tags aus Diesem extrahiert und in einem Vector speichert. Dabei wird ein Iterator erzeugt, mit dem durch alle gefundenen Ergebnisse mittels einer While Schleife iteriert wird:

    regex reg (HTTP_REGEX);
        sregex_iterator i( make_regex_iterator(strHTML, reg)),j;
        while(i != j)
        {
            objEntry.id =(*i)[1];
            objEntry.title =(*i)[2];
            vec->push_back(objEntry);
            i++;
        }
    

    Der Code funktioniert, weil der Iterator, wenn er erhöht wird und bereits auf das letzte Element zeigt, auf 0 "umgebogen" wird. Deshalb funktioniert der Vergleihc mit dem Iterator j, der mit dem Defaultkonstruktur erzeugt wird.

    Prinzipiell funktioniert der Code, jedoch nur in 4 von 5 Fällen.
    Wenn es nicht funktioniert, passiert Folgendes:

    Die Whileschleife läuft für alle gefundenen Elemente erfolgreich durch. Der Iterator wird erhöht, und ich bekomme die Meldung:

    MS VS 2005 EE schrieb:

    Unbehandelte Ausnahme bei 0x75e0b09e in NetTest.exe: Microsoft C++-Ausnahme: std::runtime_error an Speicherposition 0x0012f014..

    Unten, im Debugbereich steht als Inhalt von this "Memory exhausted".

    Ich habe versucht, das ganze zu debuggen, aber leider ist man an einer Stelle der Sourcecode ausgegangen, und ein Assembly zu debuggen - so weitgehend sind meine Kenntnisse dann doch nicht

    Habt ihr eine Idee?

    Danke!



  • Hmmm bist du dir sicher, dass der Standartkonstruktor von sregex_iterator einen Iterator erzeugt, der auf das Ende des geparsten Textes zeigt?
    Das erscheint mir etwas gewagt...



  • Es wird ja eine std::runtime_error-Exception geworfen. Besser kanns doch erstmal nicht laufen, weil es ein kontrolliert verursachter Fehler ist. Warum fängst du sie nicht einfach ab und gibst mit what() das Problem aus? Vielleicht steht da mehr drin?



  • ich hoffe ihr könnt mit dem Ergebnis etwas anfangen: Screenshot



  • Fehler: Ausdruck kann nicht ausgewertet werden

    Klingt für mich irgendwie danach, dass der genutzte Regex falsch formatiert der sonstwie ungültig ist.

    Vielleicht kannst du ihn mal zeigen?



  • klar!

    \?datid=(.+?)\.xml.+?>(?: |(?:<.+?>))+entry\d{3}(?:<.+?>)((?:[^<])+)

    aber es tritt auch nicht immer auf, nur manchmal!



  • Hem, Exhausted heißt "aufgebraucht" oder "erchöpft". Scheint also eher ein Poblem mit Speicherknappheit zu sein? Und könte es sein, das "Memory Exhausted" in what() drin steht? 🙄
    Wie groß ist denn die HTML-Datei?



  • der Fehler tritt aber merkwürdigerweise auch bei etwas kleinereren Dateien auf.. 😞
    Merkwürdig ist halt die Stelle, an der das Problem auftritt. Es läuft in jedem Fall für alle gefundenen Ergebnisse durch, und erst, wenn der Iterator erhöht wird, wenn er auf das letzte Element zeigt, und dann auf NULL umgebogen werden soll, also bei der Methode "next", tritt dieser Fehler auf. Ich bin zwar kein Experte, aber ist es nicht merkwürdig, dass an dieser Stelle ein Speicherproblem auftritt, wenn die speicherintensive Verarbeitung eigentich schon abgeschlossen ist?

    Die HTML Seiten sind übrigens ca. 32kb groß.



  • Ich habe mal in die Doku geschaut:

    Throws: std::runtime_error if the complexity of matching the expression against an N character string begins to exceed O(N2), or if the program runs out of stack space while matching the expression (if Boost.regex is configured in recursive mode), or if the matcher exhausts it's permitted memory allocation (if Boost.regex is configured in non-recursive mode).

    Also anscheinend kann man das konfigurieren und diese Exception ist, wie von mir oben gesagt, ein kontrollierter Fehler.

    Hast du durch diese Exception einen Nachteil? Also stimmt dann das Ergebnis nicht?
    Fang die Exception ab und und dann beendet sich halt die while-Schleife. Eine Exception kann schliesslich auch als Abbruchbedingung herhalten. Kann, muß nicht...

    Ansonst kannst du versuchen die Konfig von Boost.regex in den recursive mode umstellen zu versuchen und auf Besserung hoffen.



  • der recursive mode hat leider keine veränderung gebracht..

    klar kann ich die exception nutzen, aber irgendwie sträuben sich mir da die nackenhaare 😉 würde halt shcon gerne wissen, warum es manchmal auch so funktioniert



  • ".+?" irgendein zeichen, mindestens einmal oder auch gar nicht? ich schätz mal deine regexp sorgt dafür, dass die match-tiefe ins bodenlose wächst und nach was weiss ich, vielleicht 1 mio. versuchen, steigt die lib aus.
    würd die regexp ein bisschen optimieren und trimmen.



  • na ja, eigentlich macht das "?" das Plus lazy, weswegen der Term eigentlich nicht ins Bodenlose laufen sollte. Tut er ja in 80% der Fälle auch nicht. Und selbst bei den Fällen, wo das Programm abbricht, wurden vorher korrekt (und in minimaler Zeit) alle Capturings ausgegeben.

    Was würdest du denn vorschlagen bezüglich des Terms?


Anmelden zum Antworten