Freigeben über


_set_new_handler

Übergibt die Steuerung an den Fehlerbehandlungsmechanismus, wenn der new-Operator keine Speicherbelegung vornehmen kann. Der Microsoft C++-Compiler verwendet diese Funktion, um sie in der Standardbibliothek zu implementieren std::set_new_handler .

Syntax

_PNH _set_new_handler( _PNH pNewHandler );

Parameter

pNewHandler
Zeiger zu der von der Anwendung bereitgestellten Speicherbehandlungsfunktion. Ein Argument von 0 oder nullptr bewirkt, dass der neue Handler entfernt wird.

Rückgabewert

Gibt einen Zeiger zu der vorherigen Ausnahmebehandlungsfunktion zurück, die von _set_new_handler registriert wurde, sodass die vorherige Funktion später wiederhergestellt werden kann. Wenn keine vorherige Funktion festgelegt wurde, kann der Rückgabewert verwendet werden, um das Standardverhalten wiederherzustellen. Dieser Wert kann 0 oder 0 sein nullptr .

Hinweise

Mit der C++-Funktion _set_new_handler wird eine Funktion für die Ausnahmebehandlung angegeben, die die Steuerung übernimmt, wenn der new-Operator keinen Arbeitsspeicher zuordnen kann. Wenn new fehlschlägt, ruft das Laufzeitsystem automatisch die Ausnahmebehandlungsfunktion auf, die als Argument an _set_new_handler übergeben wurde. _PNH, definiert in <new.h>, ist ein Zeiger auf eine Funktion, die Typ int zurückgibt und ein Argument vom Typ size_tverwendet. Geben Sie mithilfe von size_t den zuzuordnenden Speicherplatz an.

Es gibt keinen Standardhandler.

_set_new_handler ist im Wesentlichen ein Garbage Collection-Schema. Das Laufzeitsystem wiederholt die Zuordnung jedes Mal, wenn die Funktion einen Wert ungleich null zurückgibt, und schlägt fehl, wenn die Funktion 0 zurückgibt.

Ein Vorkommen der _set_new_handler-Funktion in einem Programm registriert die Ausnahmebehandlungsfunktion, die in der Argumentliste mit dem Laufzeitsystem angegeben wird:

// _set_new_handler1.cpp
#include <new.h>

int handle_program_memory_depletion( size_t )
{
   // Your code
}

int main( void )
{
   _set_new_handler( handle_program_memory_depletion );
   int *pi = new int[BIG_NUMBER];
}

Standardmäßig ist der globale Zustand der _set_new_handler Funktion auf die Anwendung festgelegt. Informationen zum Ändern finden Sie im Global state in the CRT.

Sie können die Adresse der Funktion speichern, die zuletzt an die _set_new_handler-Funktion, übergeben wurde, und sie später reaktivieren:

   _PNH old_handler = _set_new_handler( my_handler );
   // Code that requires my_handler
   // . . .
   _set_new_handler( old_handler )
   // Code that requires old_handler
   // . . .

Die C++ _set_new_mode -Funktion legt den neuen Handlermodus für malloc. Der neue Handlermodus gibt an, ob bei einem Fehler malloc die neue Handlerroutine aufrufen soll, wie dies von _set_new_handler festgelegt ist. Ruft standardmäßig die neue Handlerroutine nicht auf, malloc wenn Speicher nicht zugewiesen werden kann. Sie können dieses Standardverhalten überschreiben, sodass, wenn malloc Speicher nicht belegen kann,malloc die neue Handlerroutine genauso aufruft wie der new-Operator, wenn dieser aus demselben Grund fehlschlägt. Um die Standardeinstellung außer Kraft zu setzen, rufen Sie _set_new_mode(1); frühzeitig in Ihrem Programm auf, oder verknüpfen Sie es mit newmode.obj.

Wenn eine benutzerdefinierte operator new Funktion bereitgestellt wird, werden die neuen Handlerfunktionen nicht automatisch beim Fehler aufgerufen.

Weitere Informationen finden Sie in new delete der C++-Sprachreferenz.

Es gibt einen einzelnen _set_new_handler Handler für alle dynamisch verknüpften DLLs oder ausführbaren Dateien in einem einzelnen Prozess. Auch wenn Sie aufrufen _set_new_handler, wird der Handler möglicherweise durch einen anderen ersetzt. Alternativ kann der neue Handler einen Handler ersetzen, der von einer anderen DLL oder ausführbaren Datei in Ihrem Prozess festgelegt wurde.

Anforderungen

Funktion Erforderlicher Header
_set_new_handler <new.h>

Weitere Informationen zur Kompatibilität finden Sie unter Kompatibilität.

Beispiel

In diesem Beispiel wird die Steuerung übertragen MyNewHandler, wenn die Zuordnung fehlschlägt. Das argument, an MyNewHandler das übergeben wird, ist die Anzahl der angeforderten Bytes. Der zurückgegebene MyNewHandler Wert ist ein Flag, das angibt, ob die Zuordnung erneut versucht werden soll: Ein Wert ungleich Null gibt an, dass die Zuordnung erneut versucht werden soll, und ein Nullwert gibt an, dass die Zuordnung fehlgeschlagen ist.

// crt_set_new_handler.cpp
// Build for x86. 
// WARNING: This code intentionally allocates memory until an allocation fails.
// Running this code can cause your system to become non-responsive.
#include <iostream>
#include <new>
#include <new.h>

static const int Big_number = 0x03FFFFFF;

struct MemoryHog {
    int pork[Big_number];
};

class MemoryReserve {
    MemoryHog* reserved = nullptr;
public:
    MemoryReserve() {
        reserved = new MemoryHog();
    }
    ~MemoryReserve() noexcept {
        if (reserved != nullptr)
            delete reserved;
    }
    bool free_reserve() noexcept {
        if (reserved != nullptr) {
            delete reserved;
            reserved = nullptr;
            return true; // return true if memory freed
        }
        return false; // reserved memory exhausted.
    }
};

// Global singleton for a MemoryReserve object
static MemoryReserve reserve{};

// Define a function to be called if new fails to allocate memory.
int MyNewHandler(size_t /* unused */)
{
    // Call a function to recover some heap space. Return 1 on success.
    if (reserve.free_reserve()) {
        std::cerr << "MyNewHandler: Released reserved memory.\n";
        return 1;
    }
    std::cerr << "MyNewHandler: Reserved memory exhausted.\n";
    return 0;
}

static const int max_depth = 16; // recursion depth limiter
static int depth = 0;

void RecurseAlloc() {
    MemoryHog* piggy = new MemoryHog{};
    if (++depth < max_depth) // Recurse until memory exhausted or max_depth
        RecurseAlloc();
    depth--;
    delete piggy;
    return;
}

int main()
{
    try {
        _set_new_handler(MyNewHandler); // Set handler for new.
        RecurseAlloc();
    }
    catch (std::bad_alloc& ex) {
        std::cerr << "bad_alloc caught: " << ex.what() << '\n';
    }
}

/* Output:
MyNewHandler: Released reserved memory.
MyNewHandler: Reserved memory exhausted.
bad_alloc caught: bad allocation
*/

Siehe auch

Speicherzuweisung
calloc
free
realloc