_set_new_handler
operatör bellek ayıramazsa new
denetimi hata işleme mekanizmanıza aktarır. Microsoft C++ derleyicisi, standart kitaplıkta uygulamak std::set_new_handler
için bu işlevi kullanır.
Sözdizimi
_PNH _set_new_handler( _PNH pNewHandler );
Parametreler
pNewHandler
Uygulama tarafından sağlanan bellek işleme işlevinin işaretçisi. 0 bağımsız değişkeni veya nullptr
yeni işleyicinin kaldırılmasına neden olur.
Dönüş değeri
önceki işlevin daha sonra geri yüklenebilmesi için tarafından _set_new_handler
kaydedilen önceki özel durum işleme işlevine yönelik bir işaretçi döndürür. Önceki bir işlev ayarlanmamışsa, varsayılan davranışı geri yüklemek için dönüş değeri kullanılabilir. Bu değer veya 0 olabilir nullptr
.
Açıklamalar
C++ _set_new_handler
işlevi, işleç belleği ayıramazsa new
denetim elde eden bir özel durum işleme işlevi belirtir. Başarısız olursa new
, çalışma zamanı sistemi bağımsız değişken _set_new_handler
olarak geçirilen özel durum işleme işlevini otomatik olarak çağırır. _PNH
içinde tanımlanan <new.h>
, türü döndüren ve türünde int
bir bağımsız değişken alan bir işlevin işaretçisidir size_t
. Ayrılacak alan miktarını belirtmek için kullanın size_t
.
Varsayılan işleyici yoktur.
_set_new_handler
temelde bir çöp toplama düzenidir. Çalışma zamanı sistemi, işleviniz sıfır olmayan bir değer döndürdüğünde ayırmayı yeniden dener ve işleviniz 0 döndürürse başarısız olur.
İşlevin _set_new_handler
bir programdaki oluşumu, bağımsız değişken listesinde belirtilen özel durum işleme işlevini çalışma zamanı sistemine kaydeder:
// _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];
}
Varsayılan olarak, işlevin _set_new_handler
genel durumunun kapsamı uygulama olarak belirlenmiştir. Bunu değiştirmek için bkz . CRT'de Genel durum.
İşleve en son geçirilen _set_new_handler
işlev adresini kaydedebilir ve daha sonra yeniden devreye alabilirsiniz:
_PNH old_handler = _set_new_handler( my_handler );
// Code that requires my_handler
// . . .
_set_new_handler( old_handler )
// Code that requires old_handler
// . . .
C++ _set_new_mode
işlevi için malloc
yeni işleyici modunu ayarlar. Yeni işleyici modu, hata malloc
durumunda tarafından _set_new_handler
ayarlanan yeni işleyici yordamının çağrılıp çağrılmayacağını belirtir. Varsayılan olarak, malloc
bellek ayırma hatasında yeni işleyici yordamını çağırmaz. Bu varsayılan davranışı geçersiz kılarak bellek malloc
ayrılamaması durumunda malloc
yeni işleyici yordamını işlecin aynı nedenden dolayı başarısız olduğu gibi new
çağırmasını sağlayabilirsiniz. Varsayılanı geçersiz kılmak için, programınızda erken çağrı veya _set_new_mode(1);
ile newmode.obj
bağlantı oluşturun.
Kullanıcı tanımlı operator new
bir sağlanmışsa, yeni işleyici işlevleri hata durumunda otomatik olarak çağrılmaz.
Daha fazla bilgi için bkz new
. ve delete
C ++ Dil Başvurusu.
Tek bir _set_new_handler
işlemdeki tüm dinamik olarak bağlı DLL'ler veya yürütülebilir dosyalar için tek bir işleyici vardır. çağırsanız _set_new_handler
bile, işleyiciniz başka bir ile değiştirilebilir. Veya yeni işleyiciniz, işleminizdeki başka bir DLL veya yürütülebilir dosya tarafından ayarlanan bir işleyicinin yerini alabilir.
Gereksinimler
İşlev | Gerekli başlık |
---|---|
_set_new_handler |
<new.h> |
Daha fazla uyumluluk bilgisi için bkz . Uyumluluk.
Örnek
Bu örnekte, ayırma başarısız olduğunda denetim öğesine MyNewHandler
aktarılır. geçirilen MyNewHandler
bağımsız değişken, istenen bayt sayısıdır. kaynağından MyNewHandler
döndürülen değer, ayırmanın yeniden denenip denenmeyeceğini belirten bir bayraktır: sıfır olmayan bir değer ayırmanın yeniden denenmesi gerektiğini, sıfır değeri ise ayırmanın başarısız olduğunu gösterir.
// 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
*/