_set_new_handler

Przesyła kontrolę do mechanizmu obsługi błędów, jeśli new operator nie może przydzielić pamięci. Kompilator języka Microsoft C++ używa tej funkcji do implementacji std::set_new_handler w standardowej bibliotece.

Składnia

_PNH _set_new_handler( _PNH pNewHandler );

Parametry

pNewHandler
Wskaźnik do funkcji obsługi pamięci dostarczonej przez aplikację. Argument 0 lub nullptr powoduje usunięcie nowej procedury obsługi.

Wartość zwracana

Zwraca wskaźnik do poprzedniej funkcji obsługi wyjątków zarejestrowanych przez _set_new_handlerelement , aby można było przywrócić poprzednią funkcję później. Jeśli nie ustawiono żadnej poprzedniej funkcji, wartość zwracana może służyć do przywrócenia domyślnego zachowania. Może to być nullptr wartość lub 0.

Uwagi

Funkcja języka C++ _set_new_handler określa funkcję obsługi wyjątków, która uzyskuje kontrolę, jeśli new operator nie może przydzielić pamięci. W przypadku new niepowodzenia system czasu wykonywania automatycznie wywołuje funkcję obsługi wyjątków, która została przekazana jako argument do _set_new_handler. _PNH, zdefiniowany w , <new.h>jest wskaźnikiem do funkcji zwracającej typ int i przyjmuje argument typu size_t. Użyj size_t polecenia , aby określić ilość miejsca do przydzielenia.

Nie ma domyślnej procedury obsługi.

_set_new_handler jest zasadniczo schematem odzyskiwania pamięci. System czasu wykonywania ponawia próbę alokacji za każdym razem, gdy funkcja zwraca wartość niezerową i kończy się niepowodzeniem, jeśli funkcja zwróci wartość 0.

Wystąpienie _set_new_handler funkcji w programie rejestruje funkcję obsługi wyjątków określoną na liście argumentów z systemem czasu wykonywania:

// _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];
}

Domyślnie _set_new_handler stan globalny funkcji jest zakresem aplikacji. Aby go zmienić, zobacz Stan globalny w CRT.

Możesz zapisać adres funkcji, który został ostatnio przekazany do _set_new_handler funkcji i przywrócić go później:

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

Funkcja języka C++ _set_new_mode ustawia nowy tryb obsługi dla elementu malloc. Nowy tryb obsługi wskazuje, malloc czy w przypadku niepowodzenia należy wywołać nową procedurę obsługi zgodnie z ustawieniem ._set_new_handler Domyślnie malloc nie wywołuje nowej procedury obsługi w przypadku niepowodzenia przydzielenia pamięci. To domyślne zachowanie można zastąpić, aby w przypadku malloc niepowodzenia przydzielenia pamięci malloc wywołać nową procedurę obsługi w taki sam sposób, jak new operator, gdy ulegnie awarii z tego samego powodu. Aby zastąpić wartość domyślną, wywołaj _set_new_mode(1); metodę na początku programu lub połącz z elementem newmode.obj.

Jeśli zostanie podana zdefiniowana przez operator new użytkownika, nowe funkcje obsługi nie są automatycznie wywoływane po awarii.

Aby uzyskać więcej informacji, zobacz new i delete w dokumentacji języka C++.

Istnieje jedna _set_new_handler procedura obsługi dla wszystkich dynamicznie połączonych bibliotek DLL lub plików wykonywalnych w jednym procesie. Nawet jeśli wywołasz _set_new_handlermetodę , program obsługi może zostać zastąpiony przez inną. Lub nowa procedura obsługi może zastąpić program obsługi ustawiony przez inną bibliotekę DLL lub plik wykonywalny w procesie.

Wymagania

Function Wymagany nagłówek
_set_new_handler <new.h>

Aby uzyskać więcej informacji o zgodności, zobacz Zgodność.

Przykład

W tym przykładzie, gdy alokacja zakończy się niepowodzeniem, kontrolka zostanie przeniesiona do MyNewHandlerelementu . Argument przekazany do MyNewHandler jest liczbą żądanych bajtów. Zwracana wartość to flaga wskazująca, czy należy ponowić próbę alokacji: wartość niezerowa wskazuje, że alokacja powinna zostać ponowiona MyNewHandler , a wartość zero wskazuje, że alokacja nie powiodła się.

// 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
*/

Zobacz też

Alokacja pamięci
calloc
free
realloc