_set_new_handler
new
연산자가 메모리 할당에 실패하면 오류 처리 메커니즘에 제어를 전달합니다. Microsoft C++ 컴파일러는 이 함수를 사용하여 표준 라이브러리에서 구현 std::set_new_handler
합니다.
구문
_PNH _set_new_handler( _PNH pNewHandler );
매개 변수
pNewHandler
애플리케이션에서 제공하는 메모리 처리 함수에 대한 포인터입니다. 인수가 0이거나 nullptr
새 처리기가 제거됩니다.
반환 값
나중에 이전 함수를 복원할 수 있도록 _set_new_handler
에서 등록한 이전 예외 처리 함수에 대한 포인터를 반환합니다. 이전 함수가 설정되지 않은 경우 반환 값을 사용하여 기본 동작을 복원할 수 있습니다. 이 값은 0일 nullptr
수 있습니다.
설명
C++ _set_new_handler
함수는 new
연산자가 메모리를 할당하지 못한 경우 컨트롤을 얻는 예외 처리 함수를 지정합니다. new
가 실패하는 경우 런타임 시스템은 _set_new_handler
에 대한 인수로 전달된 예외 처리 함수를 자동으로 호출합니다. _PNH
에 <new.h>
정의된 형식은 형식을 반환하고 형식 int
의 size_t
인수를 사용하는 함수에 대한 포인터입니다. size_t
를 사용하여 할당할 공간의 크기를 지정합니다.
기본 처리기는 없습니다.
_set_new_handler
는 기본적으로 가비지 수집 스키마입니다. 런타임 시스템은 함수가 0이 아닌 값을 반환할 때마다 할당을 다시 시도하고 함수가 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
가 제공되면 실패 시 새 처리기 함수가 자동으로 호출되지 않습니다.
자세한 내용은 C++ 언어 참조를 참조 new
delete
하세요.
단일 프로세스에 동적으로 연결된 모든 DLL 또는 실행 파일에 대한 단일 _set_new_handler
처리기가 있습니다. 호출 _set_new_handler
하는 경우에도 처리기가 다른 처리기로 대체될 수 있습니다. 또는 새 처리기가 프로세스에서 다른 DLL 또는 실행 파일로 설정된 처리기를 대체할 수 있습니다.
요구 사항
함수 | 필수 헤더 |
---|---|
_set_new_handler |
<new.h> |
호환성에 대한 자세한 내용은 호환성을 참조하세요.
예시
이 예제에서는 할당이 실패하면 컨트롤이 으로 MyNewHandler
전송됩니다. 전달된 인수는 요청된 MyNewHandler
바이트 수입니다. 반환 MyNewHandler
되는 값은 할당을 다시 시도해야 하는지 여부를 나타내는 플래그입니다. 0이 아닌 값은 할당을 다시 시도해야 함을 나타내고 0 값은 할당이 실패했음을 나타냅니다.
// 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
*/