_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_handler
element , 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_handler
metodę , 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 MyNewHandler
elementu . 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
*/