set_new_handler(out_of_memory)



  • Hallo,

    folgenden Zeile wird als erstes in der main Methode eines Beispielprogramms aufgerufen:

    set_new_handler(out_of_memory)

    kann mir einer sagen welchen Sinn das machen könnte?



  • Wenn vom Operator new ein Fehler kommt wird normalerweise eine Standard-Exception geworfen. Mit set_new_handler(void(*)()) legst du fest welche Funktion aufgerufen werden soll wenn new fehl schlägt anstatt dass std::bad_alloc geworfen wird. out_of_memory muss also irgendeine Funktion sein die auch noch definiert ist.



  • ... und die, sollte sie das Speicherallokationsproblem nicht beheben, bitte auch std::bad_alloc wirft oder set_new_handler(0) aufruft. Sonst könnte es große Probleme geben. Denn wenn mal kein Speicher da ist, wird der gesetzte new_handler aufgerufen (solang es nicht NULL ist). Nach dessen Abarbeitung versucht new wieder, Speicher zu alloziieren. Wenn das nicht klappt, kommmt wieder der new_handler zum Einsatz, und wenn der sich nicht geändert hat wird er nix tun können usw...



  • pumuckl schrieb:

    ... und die, sollte sie das Speicherallokationsproblem nicht beheben, bitte auch std::bad_alloc wirft oder set_new_handler(0) aufruft.

    darf man das? oder sollte man lieber set_new_handler(alterGemerkterHandler) aufrufen?



  • /edit: sorry, doppelpost 😞



  • Man darf alles, was nicht dazu führt, dass du in den entsprechenden Teufelskreis kommst. der newhandler ist standardmäßig afaik auf 0 gesetzt, und in dem Fall schmeißt operator new den std::bad_alloc (ist auch eines der Dinge, die man beachten muss, wenn man den "operator new" überlädt). Man kann ihn also selbst auf 0 setzen oder selbst bad_alloc werfen, oder gucken, ob ein anderer new_handler nicht mehr Glück hat. Im letzten Fall muss man aber auch wieder aufpassen, dass man nicht 5 verschiedene new_handler hat, die das Problem dann lustig im Kreis rumreichen...

    Ich muss hier wiedermal Werbung für den heiß geliebten Scott Meyers machen ("effective C++" und "more effective C++"), der hat die Geschichte mit operator new und new_handlern etc. auch gut mit abgedeckt. Ist in meinen Augen mit das schwierigste und kniffligste Thema an C++...



  • pumuckl schrieb:

    Man darf alles, was nicht dazu führt, dass du in den entsprechenden Teufelskreis kommst.

    naja, (char)0=0; läßt einen auch aus dem teufelskreis fliegen. aber ich denke, wir sind uns einig, daß man das nicht darf. weil dann nähmlich undefiniert ist, ob destruktoren noch aufgerufen werden und meine datenbank noch geschrieben wird.

    und throw 4711; wirft einen auch raus. aber ich denke, wir sind uns einig, daß man das nicht darf. weil nähmlich der benutzer von new damit echt nicht rechnet aber er eine bad_alloc fein behandeln würde.

    und set_new_handler(0) wirf einen auch raus. aber ich denke, wir sollten uns einig sein, daß man das nicht darf. weil nähmlich die grafik-engine das ganze ram mit texturen, vorausberechneten bewegungsstuden und weltdaten vollhaut, alles sachen, die sich mehr oder weniger schnell laden, entpacken oder berechnen lassen. also ein cache ist es. und durch ein statisches objekt wird ein newhandler der grafik-engine etabliert, der die cache-daten wegwirft, wenn speicher gebraucht wird. und du machst set_new_handler(0) (nebst exitus programmus). das war mit meiner durchaus rhetorischen frage gemeint, ob man das machen dürfe.


Anmelden zum Antworten