Fehler bei new abfangen, freien Speicher ermitteln



  • Ich habe sehr große Arrays die nicht unbedingt in den freien Speicher passen. Das möchte ich aber vor dem Ausführen von new wissen, damit nicht die auslagerungsdatei bemüht wird.

    Zudem möchte ich abfangen können falls new komplett fehl schlägt. Habe schon erlebt das mein Programm bei new abgestürzt ist als ich versehentlich mehrere Gigabyte addressieren wollte. Wie fange ich das zur Laufzeit ab?

    Matthias



  • new gibt 0 zurück, wenn es fehlschlägt.



  • @drakon: nö.
    wenn new fehlschlägt, kannst du mit catch bad_alloc fangen.
    oder du verwendest das nothrow- new , welches dir 0 im fall einer fehlgeschlagenen allokation zurückgibt.

    allerdings rate ich dir, dein speicherdesign zu überdenken. musst du wirklich so viel platz auf einmal reservieren? (das im vorhinein abzufragen geht mit standardmitteln nicht)



  • queer_boy schrieb:

    @drakon: nö.
    wenn new fehlschlägt, kannst du mit catch bad_alloc fangen.
    oder du verwendest das nothrow- new , welches dir 0 im fall einer fehlgeschlagenen allokation zurückgibt.

    allerdings rate ich dir, dein speicherdesign zu überdenken. musst du wirklich so viel platz auf einmal reservieren? (das im vorhinein abzufragen geht mit standardmitteln nicht)

    Sorry, habe gedacht, dass ich das mal wo gelesen habe.. 😮

    Habe jetzt aber mal probiert den Speicher so zu füllen, um es zu überprüfen, aber es ist gar nicht so einfach. 😃



  • vielleicht solltest du in dem fall lieber im internet nach infos suchen und es nicht selbst ausprobieren 😃

    nothrow-new funktioniert übrigens so:

    template <class T>
    T* foo ()
    {
       return new (nothrow) T;
    }
    

    /edit: <new> inkludieren dafür.



  • queer_boy schrieb:

    vielleicht solltest du in dem fall lieber im internet nach infos suchen und es nicht selbst ausprobieren 😃
    [/cpp]

    Naja.. Ich wollte es zuerst einfach mit einem sehr grossen Array versuchen, aber das geht ja nicht mal. 😃
    Ne einfache Schleife tuts ja dann hald auch. Räum ich hald nachher nicht mehr.. 😉



  • drakon schrieb:

    new gibt 0 zurück, wenn es fehlschlägt.

    Eine Ergänzung:
    Da es noch immer Leute gibt die noch immer mit nicht Standardkonformen Compilern arbeiten (Scheinbar ist z.B. VC++6 ja doch noch verbreitet, zumindestens in realen Projekten), möchte ich das nicht ganz ausschließen.

    Laut C++98 Standard wirft new eine Exception, und nach Standard sind auch Exceptions aktiv. In sofern haben die Vorposter vollkommen recht.

    In einer Prä-Standard Umgebung oder falls man Exceptions deaktiviert, wird die Rückgabe von 0 durchaus eine alternative Möglichkeit sein. Bei manchen der alten Compiler gibt es aber eine Möglichkeit auf das Standardkonforme Verhalten zu wechseln (ich glaube bei VC++6 z.b. durch ein include <new>).

    Bedingt dadurch das noch etliche Tutorials und Bücher am Standard vorbei geschrieben sind (oder schlicht und ergreifend keine Aktualisierung erfahren haben) kann es sein das man aber das alte Verhalten irgendwo gelesen hat. Dies gilt aber eigentlich seit 10 Jahren nicht mehr.

    cu André



  • @OT: Ich nehme mal sehr stark an, dass du std::vector<> benutzt an Stelle von normalen Arrays, schließlich bist du so schlau und weißt, dass vector<> dir tausendfach mehr Arbeit und Sorgen abnimmt, als dir der gerade bei großen Datenmengen geradezu minimale Mehraufwand dir je bereiten wird. Wenn du jetzt zu so großen Datenmengen kommst, dass du Angst haben musst, dass sie nicht mehr am Stück in den Speicher passen, dann könntest du beispielsweise auf deque<> umsteigen. Die speichert nämlich nicht alles an einem Stück wie Arrays und vector<>, sondern teilt das Array in mundgerechte Happen, zugegebenermaßen mit etwas mehr Overhead, aber immernoch in durchaus akzeptablem Rahmen.
    Gegen das Schreiben der Auslagerungsdatei kannst du meines Wissens nicht viel machen mit Standard C++. Wäre auch blöd, stell dir vor du hast irgendein riesenprogramm laufen das fast den gesamten Speicher frisst und hast dann dein selbstgeschriebenes Programm das sich durch mangelnden freien Speicher einschüchtern lässt und Angst vorm Auslagern hat - das Programm würde sehr schnell aufhören zu arbeiten, denn ohne Speicher gehts halt nicht.



  • pumuckl schrieb:

    ...deque<> ...zugegebenermaßen mit etwas mehr Overhead, aber immernoch in durchaus akzeptablem Rahmen....

    .. und bestimmt nicht mit mehr Overhead als eine selbstgestrickte Lösung (die kann ja auch nicht zaubern).

    Gruß,

    Simon2.



  • @asc
    Danke für die Ergänzung. Ich weiss wirklich nicht mehr, wie ich drauf gekommen bin. Habe irgendwie einfach gedacht, dass es logisch wäre. Jedoch "weiss" ich, wie ich nachher gemerkt habe EIGENTLICH, dass ein exception geworfen wird, war mir einfach, wo ich das geschrieben habe nicht mehr präsent.

    Aber kann es sein, dass es gar nicht so schnell geworfen wird?
    Ich habe mal eine endlosschleife laufen lassen, bad_alloc wird gefangen. Jedoch hat sich mein Speicher gemütlich gefüllt, ohne dass bad_alloc geworfen wurde. Sprich: "Wann wird bad_alloc effektiv geworfen"?



  • drakon schrieb:

    Sprich: "Wann wird bad_alloc effektiv geworfen"?

    Das wird wohl von der Implementierung des Allokator abhängen. Wenn die Systemfunktionen malloc etc verwendet weden, werden es wohl die Speicherverwaltungsstrategien des OS entscheiden.


Anmelden zum Antworten