std::bad allocator zur Laufzeit



  • @Quiche-Lorraine sagte in std::bad allocator zur Laufzeit:

    Regular expressions library?

    ...oder die hier: https://github.com/hanickadot/compile-time-regular-expressions wenn die REs zur Compilezeit feststehen.



  • @Finnegan sagte in std::bad allocator zur Laufzeit:

    oder der Speicher zu fragmentiert für Anforderung ist

    Speicherfragmentation ist kein Problem, was bei einem halbwegs aktuellen OS mit virtueller Speicherverwaltung eine Rolle spielt. Die logischen Speicherseiten können wild im physikalischen Speicher verteilt sein, die Applikation sieht davon nichts. Es kann nur dann zu einem Problem werden, wenn die OS interne Verwaltungsstruktur über zu laufen droht. Dann wird eine Defragmentatierung gemacht, wovon die Applikation nichts mitbekommt. Sie wird kurz angehalten und die physikalischen Speicherseiten umgelagert, so dass weniger Seiten verwaltet werden müssen.

    Probleme mit Fragmentation sieht man heute eigentlich nur noch bei embedded Laufzeitumgebungen, oder man programmiert für ein Retrosystem.



  • @john-0 sagte in std::bad allocator zur Laufzeit:

    @Finnegan sagte in std::bad allocator zur Laufzeit:

    oder der Speicher zu fragmentiert für Anforderung ist

    Speicherfragmentation ist kein Problem, was bei einem halbwegs aktuellen OS mit virtueller Speicherverwaltung eine Rolle spielt.

    Das wohl, aber ich denke da hat die Malloc-Implementierung der verwendeten C-Runtime auch noch ein Wörtchen mitzureden. Dort könnte ebenfalls eine feingranularere Fragmentierung auftreten (unterhalb der Page-Ebene), die dazu führt, dass das Programm übermässig viele Seiten vom OS anfordert, ohne diese wieder zurückzugeben. Da könnte dann ein OS auch nicht viel gegen tun.

    Wie relevant das letztendlich ist, kann ich aber nicht sagen. Ich wollte hier nur ein paar Gründe auflisten, weshalb es zu einem bad_alloc kommen kann. Ich vermute stark @Ichwerdennsonst läuft hier einfach in eine klassische OOM-Situation.



  • @Finnegan sagte in std::bad allocator zur Laufzeit:

    Das wohl, aber ich denke da hat die Malloc-Implementierung der verwendeten C-Runtime auch noch ein Wörtchen mitzureden. Dort könnte ebenfalls eine feingranularere Fragmentierung auftreten (unterhalb der Page-Ebene), die dazu führt, dass das Programm übermässig viele Seiten vom OS anfordert, ohne diese wieder zurückzugeben. Da könnte dann ein OS auch nicht viel gegen tun.

    Aus Performancegründen wird mittlerweile exzessiv Gebrauch von Memory Overcommitment gemacht. D.h. wenn man wirklich ein Problem mit dem Speicher bekommt, wird mit Sicherheit kein bad_alloc mehr geworfen, sondern das OS kickt das Programm aus dem System.

    Wie relevant das letztendlich ist, kann ich aber nicht sagen. Ich wollte hier nur ein paar Gründe auflisten, weshalb es zu einem bad_alloc kommen kann. Ich vermute stark @Ichwerdennsonst läuft hier einfach in eine klassische OOM-Situation.

    Danach sieht es aus.



  • @john-0
    oom ist schwierig, da ich dem Programm nicht wirklich viel übergeben habe, grob geschätzt müsste es 100 byte ram verbraucht haben und es sollte ja wohl problemlos tausendmal so viel verbrauchen dürfen. An der For-Schleife kann es nicht liegen, die hört nach der Länge des Strings sicher auf. Wie gesagt ist es erst nach Hinzufügen in Zeile 10-12 dazu gekommen. Vielleicht ist das auch logisch immerhin versuche ich ein zusammenhängendes Stück Speicher mittendrin aufzublähen. Andererseits sollte ich mir als Programmierer selbst bei C++ darüber keine Gedanken machen müssen, das ist Aufgabe der stdlib. Vielleicht ist auch irgendwo eine Schleife kaputt und das Programm hört gar nicht auf Speicher zu beschlagnamen, aber wie gesagt die For-Schleife ist eigentlich wasserdicht.
    Ob der Speicher zusammenhängt ist mir letzendlich egal, ich weiß nur das er es bei Vector tut. Windows zerschießt den Performance-Vorteil wahrscheinlich durch Paging. Vielleicht erkennt Windows aber auch die Chance. Wieweit ich Assembler kenne, sind zusammenhängende Bereiche u.a. wegen rep/repz/repnz (jedenfalls bei x86) und weil man Adressen nicht aus dem Speicher laden muss effizienter. Also folgt, dass es guter Programmierstil ist, das wenn möglich so zu machen. Übrigens ist die Funktion dafür gedacht, die Eingabe zu ordnen. Später wird sehr viel darauf zugegriffen.
    @Finnegan
    Statt list vector zu nehmen ist eine gute Idee. Das hab ich schließlich auch gemacht und jetzt kommt kein bad::allocator mehr 🙂 Also danke schonmal für die Hilfe



  • Du denkst über völlig falsche Dinge nach. Sag ja nur. VERGISS SOFORT alle Gedanken über Fragmentierung, Assembler, möglicherweise problematische Stdlib und anderen Kram.

    Stattdessen hinterfrage in deinem Programm:

    • die Loops
    • jedes new und delete (es sollte keines geben)

    Was soll deine Funktion stringnachRegeln tun? Beschreibe das mal exakt. Und dann schreibe Tests dazu. Was soll rauskommen, wenn du sie mit einem leeren String aufrufst? Was wenn du "123abc" oder "\w+" eingibst? Allein schon der Rückgabetyp ist doch völlig unklar - ein String und eine Liste von Liste von String - aber was soll da semantisch drinstehen?

    Ansonsten: aktiviere Address- und Memory-Sanitizer.



  • ich weiß jetzt woran es liegt es ist diese Zeile:

    
    r->at((wargleich?Gleiches:(r->size()-1))).zu.push_back(std::vector<std::string>());
    

    Offenbar wird dadurch alles gelöscht

    Absurderweise aber nur, wenn ich es in einer If-Schleife ausführe
    Jedenfalls nochmal danke
    jetzt funktionierts



  • @Ichwerdennsonst sagte in std::bad allocator zur Laufzeit:

    ich weiß jetzt woran es liegt es ist diese Zeile:

    
    r->at((wargleich?Gleiches:(r->size()-1))).zu.push_back(std::vector<std::string>());
    

    Offenbar wird dadurch alles gelöscht

    Absurderweise aber nur, wenn ich es in einer If-Schleife ausführe
    Jedenfalls nochmal danke
    jetzt funktionierts

    If ist keine Schleife und gelöscht wird da gar nix.



  • @Ichwerdennsonst sagte in std::bad allocator zur Laufzeit:

    Ob der Speicher zusammenhängt ist mir letzendlich egal, ich weiß nur das er es bei Vector tut. Windows zerschießt den Performance-Vorteil wahrscheinlich durch Paging. Vielleicht erkennt Windows aber auch die Chance.

    Sollte dein Thema eher nicht Parser oder Automaten sein?

    Ich habe da mal einen schönen Link gefunden: Regular Expression Matching Can Be Simple And Fast



  • @Quiche-Lorraine sagte in std::bad allocator zur Laufzeit:

    Sollte dein Thema eher nicht Parser oder Automaten sein?

    Ich habe da mal einen schönen Link gefunden: Regular Expression Matching Can Be Simple And Fast

    Ja, ich denke auch dass sich die Diskussion hier zu sehr um Folgeprobleme dreht, die wahrscheinlich durch - gelinde ausgedrückt - etwas holprigen Code selbst geschaffen sind. Nicht vergessen: Man will eigentlich meistens keine Bohrer, sondern Löcher 😉


Anmelden zum Antworten