You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
helpviewer_keywords: ["_set_new_handler function", "set_new_handler function", "error handling", "transferring control to error handler"]
11
11
ms.assetid: 1d1781b6-5cf8-486a-b430-f365e0bb023f
12
12
---
13
-
# _set_new_handler
13
+
# `_set_new_handler`
14
14
15
-
Transfers control to your error-handling mechanism if the **`new`** operator fails to allocate memory.
15
+
Transfers control to your error-handling mechanism if the **`new`** operator fails to allocate memory. The Microsoft C++ compiler uses this function to implement [`std::set_new_handler`](../../standard-library/new-functions.md#set_new_handler) in the standard library.
Pointer to the application-supplied memory handling function. An argument of 0 causes the new handler to be removed.
25
+
*`pNewHandler`*\
26
+
Pointer to the application-supplied memory handling function. An argument of 0 or `nullptr` causes the new handler to be removed.
27
27
28
-
## Return Value
28
+
## Return value
29
29
30
-
Returns a pointer to the previous exception handling function registered by **_set_new_handler**, so that the previous function can be restored later. If no previous function has been set, the return value can be used to restore the default behavior; this value can be **NULL**.
30
+
Returns a pointer to the previous exception handling function registered by **`_set_new_handler`**, so that the previous function can be restored later. If no previous function has been set, the return value can be used to restore the default behavior. This value can be `nullptr` or 0.
31
31
32
32
## Remarks
33
33
34
-
The C++ **_set_new_handler** function specifies an exception-handling function that gains control if the **`new`** operator fails to allocate memory. If **`new`** fails, the run-time system automatically calls the exception-handling function that was passed as an argument to **_set_new_handler**. **_PNH**, defined in New.h, is a pointer to a function that returns type **`int`** and takes an argument of type **size_t**. Use **size_t** to specify the amount of space to be allocated.
34
+
The C++ **`_set_new_handler`** function specifies an exception-handling function that gains control if the **`new`** operator fails to allocate memory. If **`new`** fails, the run-time system automatically calls the exception-handling function that was passed as an argument to **`_set_new_handler`**. **`_PNH`**, defined in `<new.h>`, is a pointer to a function that returns type **`int`** and takes an argument of type **`size_t`**. Use **`size_t`** to specify the amount of space to be allocated.
35
35
36
-
There is no default handler.
36
+
There's no default handler.
37
37
38
-
**_set_new_handler** is essentially a garbage-collection scheme. The run-time system retries allocation each time your function returns a nonzero value and fails if your function returns 0.
38
+
**`_set_new_handler`** is essentially a garbage-collection scheme. The run-time system retries allocation each time your function returns a nonzero value and fails if your function returns 0.
39
39
40
-
An occurrence of the **_set_new_handler** function in a program registers the exception-handling function specified in the argument list with the run-time system:
40
+
An occurrence of the **`_set_new_handler`** function in a program registers the exception-handling function specified in the argument list with the run-time system:
41
41
42
42
```cpp
43
-
// set_new_handler1.cpp
44
-
By default, this function's global state is scoped to the application. To change this, see [Global state in the CRT](../global-state.md).
45
-
43
+
// _set_new_handler1.cpp
46
44
#include <new.h>
47
45
48
46
int handle_program_memory_depletion( size_t )
@@ -57,7 +55,9 @@ int main( void )
57
55
}
58
56
```
59
57
60
-
You can save the function address that was last passed to the **_set_new_handler** function and reinstate it later:
58
+
By default, the **`_set_new_handler`** function's global state is scoped to the application. To change it, see [Global state in the CRT](../global-state.md).
59
+
60
+
You can save the function address that was last passed to the **`_set_new_handler`** function and reinstate it later:
@@ -68,81 +68,109 @@ You can save the function address that was last passed to the **_set_new_handler
68
68
// . . .
69
69
```
70
70
71
-
The C++ [_set_new_mode](set-new-mode.md) function sets the new handler mode for [malloc](malloc.md). The new handler mode indicates whether, on failure, **malloc** is to call the new handler routine as set by **_set_new_handler**. By default, **malloc** does not call the new handler routine on failure to allocate memory. You can override this default behavior so that, when **malloc** fails to allocate memory, **malloc** calls the new handler routine in the same way that the **`new`** operator does when it fails for the same reason. To override the default, call:
71
+
The C++ [`_set_new_mode`](set-new-mode.md) function sets the new handler mode for [`malloc`](malloc.md). The new handler mode indicates whether, on failure, **`malloc`** is to call the new handler routine as set by **`_set_new_handler`**. By default, **`malloc`** doesn't call the new handler routine on failure to allocate memory. You can override this default behavior so that, when **`malloc`** fails to allocate memory, **`malloc`** calls the new handler routine in the same way that the **`new`** operator does when it fails for the same reason. To override the default, call `_set_new_mode(1);` early in your program or link with *`newmode.obj`*.
72
72
73
-
```cpp
74
-
_set_new_mode(1);
75
-
```
73
+
If a user-defined `operator new` is provided, the new handler functions aren't automatically called on failure.
76
74
77
-
early in your program or link with Newmode.obj.
75
+
For more information, see [`new`](../../cpp/new-operator-cpp.md) and [`delete`](../../cpp/delete-operator-cpp.md) in the *C++ Language Reference*.
78
76
79
-
If a user-defined `operator new` is provided, the new handler functions are not automatically called on failure.
80
-
81
-
For more information, see [new](../../cpp/new-operator-cpp.md) and [delete](../../cpp/delete-operator-cpp.md) in the *C++ Language Reference*.
82
-
83
-
There is a single **_set_new_handler** handler for all dynamically linked DLLs or executables; even if you call **_set_new_handler** your handler might be replaced by another or that you are replacing a handler set by another DLL or executable.
77
+
There's a single **`_set_new_handler`** handler for all dynamically linked DLLs or executables in a single process. Even if you call **`_set_new_handler`**, your handler might be replaced by another. Or, your new handler may replace a handler set by another DLL or executable in your process.
84
78
85
79
## Requirements
86
80
87
-
|Routine|Required header|
88
-
|-------------|---------------------|
89
-
|**_set_new_handler**|\<new.h>|
81
+
| Function | Required header|
82
+
|--|--|
83
+
| **`_set_new_handler`** | `<new.h>` |
90
84
91
85
For more compatibility information, see [Compatibility](../../c-runtime-library/compatibility.md).
92
86
93
87
## Example
94
88
95
-
In this example, when the allocation fails, control is transferred to MyNewHandler. The argument passed to MyNewHandler is the number of bytes requested. The value returned from MyNewHandler is a flag indicating whether allocation should be retried: a nonzero value indicates that allocation should be retried, and a zero value indicates that allocation has failed.
89
+
In this example, when the allocation fails, control is transferred to `MyNewHandler`. The argument passed to `MyNewHandler` is the number of bytes requested. The value returned from `MyNewHandler` is a flag indicating whether allocation should be retried: a nonzero value indicates that allocation should be retried, and a zero value indicates that allocation has failed.
96
90
97
91
```cpp
98
92
// crt_set_new_handler.cpp
99
-
// compile with: /c
100
-
#include<stdio.h>
93
+
// Build for x86.
94
+
// WARNING: This code intentionally allocates memory until an allocation fails.
95
+
// Running this code can cause your system to become non-responsive.
96
+
#include <iostream>
97
+
#include <new>
101
98
#include <new.h>
102
-
#defineBIG_NUMBER 0x1fffffff
103
99
104
-
int coalesced = 0;
100
+
static const int Big_number = 0x03FFFFFF;
101
+
102
+
struct MemoryHog {
103
+
int pork[Big_number];
104
+
};
105
+
106
+
class MemoryReserve {
107
+
MemoryHog* reserved = nullptr;
108
+
public:
109
+
MemoryReserve() {
110
+
reserved = new MemoryHog();
111
+
}
112
+
~MemoryReserve() noexcept {
113
+
if (reserved != nullptr)
114
+
delete reserved;
115
+
}
116
+
bool free_reserve() noexcept {
117
+
if (reserved != nullptr) {
118
+
delete reserved;
119
+
reserved = nullptr;
120
+
return true; // return true if memory freed
121
+
}
122
+
return false; // reserved memory exhausted.
123
+
}
124
+
};
125
+
126
+
// Global singleton for a MemoryReserve object
127
+
static MemoryReserve reserve{};
105
128
106
-
intCoalesceHeap()
107
-
{
108
-
coalesced = 1; // Flag RecurseAlloc to stop
109
-
// do some work to free memory
110
-
return 0;
111
-
}
112
129
// Define a function to be called if new fails to allocate memory.
113
-
intMyNewHandler(size_t size )
130
+
int MyNewHandler(size_t /* unused */)
114
131
{
115
-
printf("Allocation failed. Coalescing heap.\n");
116
-
117
-
// Call a function to recover some heap space.
118
-
return CoalesceHeap();
132
+
// Call a function to recover some heap space. Return 1 on success.
133
+
if (reserve.free_reserve()) {
134
+
std::cerr << "MyNewHandler: Released reserved memory.\n";
C++ supports dynamic allocation and deallocation of objects using the [`new`](new-operator-cpp.md) and [`delete`](delete-operator-cpp.md) operators. These operators allocate memory for objects from a pool called the free store. The **`new`** operator calls the special function [`operator new`](new-operator-cpp.md), and the **`delete`** operator calls the special function [`operator delete`](delete-operator-cpp.md).
10
-
11
-
The **`new`** function in the C++ Standard Library supports the behavior specified in the C++ standard, which is to throw a `std::bad_alloc` exception if the memory allocation fails. If you still want the non-throwing version of **`new`**, link your program with *`nothrownew.obj`*. However, when you link with *`nothrownew.obj`*, the default **`operator new`** in the C++ Standard Library no longer functions.
9
+
C++ supports dynamic allocation and deallocation of objects using the [`new`](new-operator-cpp.md) and [`delete`](delete-operator-cpp.md) operators. These operators allocate memory for objects from a pool called the *free store* (also known as the *heap*). The **`new`** operator calls the special function [`operator new`](new-operator-cpp.md), and the **`delete`** operator calls the special function [`operator delete`](delete-operator-cpp.md).
12
10
13
11
For a list of the library files in the C Runtime Library and the C++ Standard Library, see [CRT Library Features](../c-runtime-library/crt-library-features.md).
14
12
@@ -20,9 +18,9 @@ The compiler translates a statement such as this one into a call to the function
20
18
char *pch = newchar[BUFFER_SIZE];
21
19
```
22
20
23
-
If the request is for zero bytes of storage, **`operator new`** returns a pointer to a distinct object. That is, repeated calls to **`operator new`** return different pointers. If there's insufficient memory for the allocation request, **`operator new`** throws a `std::bad_alloc` exception. Or, it returns **`nullptr`** if you've linked in non-throwing **`operator new`** support.
21
+
If the request is for zero bytes of storage, **`operator new`** returns a pointer to a distinct object. That is, repeated calls to **`operator new`** return different pointers.
24
22
25
-
You can write a routine that attempts to free memory and retry the allocation. For more information, see [`_set_new_handler`](../c-runtime-library/reference/set-new-handler.md). For details on the recovery scheme, see the [Handling insufficient memory](#handling-insufficient-memory) section.
23
+
If there's insufficient memory for the allocation request, **`operator new`** throws a `std::bad_alloc` exception. Or, it returns **`nullptr`** if you've used the *placement* form `new(std::nothrow)`, or if you've linked in non-throwing **`operator new`** support. For more information, see [Allocation failure behavior](#allocation-failure-behavior).
26
24
27
25
The two scopes for **`operator new`** functions are described in the following table.
28
26
@@ -33,7 +31,7 @@ The two scopes for **`operator new`** functions are described in the following t
33
31
|**`::operator new`**| Global |
34
32
|*class-name***`::operator new`**| Class |
35
33
36
-
The first argument to**`operator new`** must be of type `size_t`, defined in \<stddef.h>, and the return type is always **`void*`**.
34
+
The first argument of**`operator new`** must be of type `size_t`, and the return type is always **`void*`**.
37
35
38
36
The global **`operator new`** function is called when the **`new`** operator is used to allocate objects of built-in types, objects of class type that don't contain user-defined **`operator new`** functions, and arrays of any type. When the **`new`** operator is used to allocate objects of a class type where an **`operator new`** is defined, that class's **`operator new`** is called.
39
37
@@ -94,24 +92,67 @@ int main()
94
92
}
95
93
```
96
94
95
+
### Allocation failure behavior
96
+
97
+
The **`new`** function in the C++ Standard Library supports the behavior specified in the C++ standard since C++98. When there's insufficient memory for an allocation request, **`operator new`** throws a [`std::bad_alloc`](../standard-library/bad-alloc-class.md) exception.
98
+
99
+
Older C++ code returned a null pointer for a failed allocation. If you have code that expects the non-throwing version of **`new`**, link your program with *`nothrownew.obj`*. The *`nothrownew.obj`* file replaces global **`operator new`** with a version that returns **`nullptr`** if an allocation fails. **`operator new`** no longer throws `std::bad_alloc`. For more information about *`nothrownew.obj`* and other linker option files, see [Link options](../c-runtime-library/link-options.md).
100
+
101
+
You can't mix code that checks for exceptions from global **`operator new`** with code that checks for null pointers in the same application. However, you can still create class-local **`operator new`** that behaves differently. This possibility means the compiler must act defensively by default and include checks for null pointer returns in **`new`** calls. For more information on a way to optimize these compiler checks, see [`/Zc:throwingnew`](../build/reference/zc-throwingnew-assume-operator-new-throws.md).
102
+
97
103
### Handling insufficient memory
98
104
99
-
Testing for failed memory allocation can be done as shown here:
105
+
The way you test for a failed allocation from a **`new`** expression depends on whether you use the standard exception mechanism, or you use a **`nullptr`** return. Standard C++ expects an allocator to throw either `std::bad_alloc` or a class derived from `std::bad_alloc`. You can handle such an exception as shown in this sample:
When you use the `nothrow` form of **`new`**, you can test for an allocation failure as shown in this sample:
124
+
125
+
```cpp
126
+
#include <iostream>
127
+
#include <new>
128
+
using namespace std;
129
+
#define BIG_NUMBER 10000000000LL
130
+
int main() {
131
+
int *pI = new(nothrow) int[BIG_NUMBER];
132
+
if ( pI == nullptr ) {
133
+
cout << "Insufficient memory" << endl;
134
+
return -1;
135
+
}
136
+
}
137
+
```
138
+
139
+
You can test for a failed memory allocation when you've used *`nothrownew.obj`* file to replace global **`operator new`** as shown here:
100
140
101
141
```cpp
102
142
#include <iostream>
143
+
#include <new>
103
144
using namespace std;
104
-
#defineBIG_NUMBER100000000
145
+
#define BIG_NUMBER 10000000000LL
105
146
int main() {
106
147
int *pI = new int[BIG_NUMBER];
107
-
if( pI == 0x0 ) {
148
+
if ( !pI ) {
108
149
cout << "Insufficient memory" << endl;
109
150
return -1;
110
151
}
111
152
}
112
153
```
113
154
114
-
There's another way to handle failed memory allocation requests. Write a custom recovery routine to handle such a failure, then register your function by calling the [`_set_new_handler`](../c-runtime-library/reference/set-new-handler.md) run-time function.
155
+
You can provide a handler for failed memory allocation requests. It's possible to write a custom recovery routine to handle such a failure. It could, for example, release some reserved memory, then allow the allocation to run again. For more information, see [`_set_new_handler`](../c-runtime-library/reference/set-new-handler.md).
115
156
116
157
## <a id="delete_operator"> </a> The `delete` operator
0 commit comments