_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_handlerkaydedilen ö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_handlerolarak geçirilen özel durum işleme işlevini otomatik olarak çağırır. _PNHiç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 mallocyeni işleyici modunu ayarlar. Yeni işleyici modu, hata malloc durumunda tarafından _set_new_handlerayarlanan 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.objbağ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_handlerbile, 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 MyNewHandleraktarı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
*/

Ayrıca bkz.

Bellek ayırma
calloc
free
realloc