_set_new_handler

Mentransfer kontrol ke mekanisme penanganan kesalahan Anda jika new operator gagal mengalokasikan memori. Pengkompilasi Microsoft C++ menggunakan fungsi ini untuk diterapkan std::set_new_handler di pustaka standar.

Sintaks

_PNH _set_new_handler( _PNH pNewHandler );

Parameter

pNewHandler
Penunjuk ke fungsi penanganan memori yang disediakan aplikasi. Argumen 0 atau nullptr menyebabkan handler baru dihapus.

Nilai hasil

Mengembalikan penunjuk ke fungsi penanganan pengecualian sebelumnya yang didaftarkan oleh _set_new_handler, sehingga fungsi sebelumnya dapat dipulihkan nanti. Jika tidak ada fungsi sebelumnya yang telah ditetapkan, nilai pengembalian dapat digunakan untuk memulihkan perilaku default. Nilai ini bisa atau nullptr 0.

Keterangan

Fungsi C++ _set_new_handler menentukan fungsi penanganan pengecualian yang mendapatkan kontrol jika new operator gagal mengalokasikan memori. Jika new gagal, sistem run-time secara otomatis memanggil fungsi penanganan pengecualian yang diteruskan sebagai argumen ke _set_new_handler. _PNH, didefinisikan dalam <new.h>, adalah penunjuk ke fungsi yang mengembalikan jenis int dan mengambil argumen jenis size_t. Gunakan size_t untuk menentukan jumlah ruang yang akan dialokasikan.

Tidak ada handler default.

_set_new_handler pada dasarnya adalah skema pengumpulan sampah. Sistem run-time mencoba kembali alokasi setiap kali fungsi Anda mengembalikan nilai bukan nol dan gagal jika fungsi Anda mengembalikan 0.

Kemunculan _set_new_handler fungsi dalam program mendaftarkan fungsi penanganan pengecualian yang ditentukan dalam daftar argumen dengan sistem run-time:

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

Secara default, _set_new_handler status global fungsi dicakup ke aplikasi. Untuk mengubahnya, lihat Status global di CRT.

Anda dapat menyimpan alamat fungsi yang terakhir diteruskan ke _set_new_handler fungsi dan memulihkannya nanti:

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

Fungsi C++ _set_new_mode mengatur mode handler baru untuk malloc. Mode handler baru menunjukkan apakah, jika gagal, malloc adalah memanggil rutinitas handler baru seperti yang ditetapkan oleh _set_new_handler. Secara default, malloc tidak memanggil rutinitas handler baru saat gagal mengalokasikan memori. Anda dapat mengambil alih perilaku default ini sehingga, ketika malloc gagal mengalokasikan memori, malloc memanggil rutinitas handler baru dengan cara yang sama seperti yang new dilakukan operator ketika gagal karena alasan yang sama. Untuk mengambil alih default, panggil _set_new_mode(1); di awal program Anda atau tautkan dengan newmode.obj.

Jika ditentukan pengguna operator new disediakan, fungsi handler baru tidak secara otomatis dipanggil pada kegagalan.

Untuk informasi selengkapnya, lihat new dan delete di Referensi Bahasa C++.

Ada satu _set_new_handler handler untuk semua DLL atau executable yang ditautkan secara dinamis dalam satu proses. Bahkan jika Anda memanggil _set_new_handler, handler Anda mungkin digantikan oleh yang lain. Atau, handler baru Anda dapat mengganti handler yang ditetapkan oleh DLL lain atau dapat dieksekusi dalam proses Anda.

Persyaratan

Function Header yang diperlukan
_set_new_handler <new.h>

Untuk informasi kompatibilitas selengkapnya, lihat Kompatibilitas.

Contoh

Dalam contoh ini, ketika alokasi gagal, kontrol ditransfer ke MyNewHandler. Argumen yang diteruskan ke MyNewHandler adalah jumlah byte yang diminta. Nilai yang dikembalikan dari MyNewHandler adalah bendera yang menunjukkan apakah alokasi harus dicoba kembali: nilai bukan nol menunjukkan bahwa alokasi harus dicoba kembali, dan nilai nol menunjukkan bahwa alokasi telah gagal.

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

Baca juga

Alokasi memori
calloc
free
realloc