_set_new_handler

new 運算子無法配置記憶體,則將控制項傳送至您的錯誤處理機制。 Microsoft C++ 編譯器會使用此函式在標準程式庫中實 std::set_new_handler 作。

語法

_PNH _set_new_handler( _PNH pNewHandler );

參數

pNewHandler
應用程式所提供記憶體處理函式的指標。 0 的引數,或 nullptr 導致移除新的處理常式。

傳回值

傳回 _set_new_handler 所註冊之先前例外狀況處理函式的指標,因此,稍後可以還原先前函式。 如果未設定任何先前的函式,則傳回值可用來還原預設行為。 此值可以是 nullptr 或 0。

備註

如果 new 運算子無法配置記憶體,則 C++ _set_new_handler 函式會指定取得控制權的例外狀況處理函式。 如果 new 失敗,執行階段系統會自動呼叫傳遞為 _set_new_handler 之引數的例外狀況處理函式。 _PNH,定義于 <new.h> 中,是傳回型 int 別並接受 型 size_t 別引數之函式的指標。 使用 size_t 來指定要配置的空間量。

沒有預設處理常式。

_set_new_handler 基本上是記憶體回收配置。 每次函式傳回非零值時,執行階段系統都會重試配置,如果函式傳回 0 則失敗。

程式中出現的 _set_new_handler 函式會向執行階段系統註冊引數清單中所指定的例外狀況處理函式:

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

根據預設,函 _set_new_handler 式的全域狀態會限定于應用程式。 若要變更它,請參閱 CRT 中的全域狀態。

您可以儲存最後傳遞至 _set_new_handler 函式的函式位址,並稍後進行恢復:

   _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 函式會設定 的新處理常式模式 malloc 。 新的處理常式模式表示失敗時,malloc 是否呼叫 _set_new_handler 所設定的新處理常式。 根據預設, malloc 不會在無法配置記憶體時呼叫新的處理常式常式。 您可以覆寫這個預設行為,因此,在 malloc 無法配置記憶體時,malloc 會呼叫新的處理常式,其方法與 new 運算子因相同原因而失敗時所執行的方法相同。 若要覆寫預設值,請在程式早期呼叫 _set_new_mode(1); ,或使用 連結 newmode.obj

如果提供使用者定義 operator new ,新的處理常式函式不會在失敗時自動呼叫。

如需詳細資訊,請參閱 new C++ 語言參考 中的 和 delete

單一進程中所有動態連結 DLL 或可執行檔都有單 _set_new_handler 一處理程式。 即使您呼叫 _set_new_handler ,您的處理常式也可能由另一個取代。 或者,您的新處理常式可能會取代進程中另一個 DLL 或可執行檔所設定的處理常式。

需求

函式 必要的標頭
_set_new_handler <new.h>

如需相容性詳細資訊,請參閱相容性

範例

在此範例中,當配置失敗時,控制權會傳送至 MyNewHandler 。 傳遞至 MyNewHandler 的引數是要求的位元組數目。 傳 MyNewHandler 回的值是旗標,指出是否應該重試配置:非零值表示應該重試配置,而零值表示配置失敗。

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

另請參閱

記憶體配置
calloc
free
realloc