diff --git a/docs/c-runtime-library/reference/set-new-handler.md b/docs/c-runtime-library/reference/set-new-handler.md
index 9a228026549..1c6e20a3c18 100644
--- a/docs/c-runtime-library/reference/set-new-handler.md
+++ b/docs/c-runtime-library/reference/set-new-handler.md
@@ -1,7 +1,7 @@
---
description: "Learn more about: _set_new_handler"
title: "_set_new_handler"
-ms.date: "4/2/2020"
+ms.date: 05/21/2022
api_name: ["_set_new_handler", "_o__set_new_handler"]
api_location: ["msvcrt.dll", "msvcr80.dll", "msvcr90.dll", "msvcr100.dll", "msvcr100_clr0400.dll", "msvcr110.dll", "msvcr110_clr0400.dll", "msvcr120.dll", "msvcr120_clr0400.dll", "ucrtbase.dll", "api-ms-win-crt-runtime-l1-1-0.dll", "api-ms-win-crt-private-l1-1-0.dll"]
api_type: ["DLLExport"]
@@ -10,9 +10,9 @@ f1_keywords: ["_set_new_handler", "set_new_handler"]
helpviewer_keywords: ["_set_new_handler function", "set_new_handler function", "error handling", "transferring control to error handler"]
ms.assetid: 1d1781b6-5cf8-486a-b430-f365e0bb023f
---
-# _set_new_handler
+# `_set_new_handler`
-Transfers control to your error-handling mechanism if the **`new`** operator fails to allocate memory.
+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.
## Syntax
@@ -22,27 +22,25 @@ _PNH _set_new_handler( _PNH pNewHandler );
### Parameters
-*pNewHandler*
-Pointer to the application-supplied memory handling function. An argument of 0 causes the new handler to be removed.
+*`pNewHandler`*\
+Pointer to the application-supplied memory handling function. An argument of 0 or `nullptr` causes the new handler to be removed.
-## Return Value
+## Return value
-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**.
+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.
## Remarks
-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.
+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 ``, 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.
-There is no default handler.
+There's no default handler.
-**_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.
+**`_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.
-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:
+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:
```cpp
-// set_new_handler1.cpp
-By default, this function's global state is scoped to the application. To change this, see [Global state in the CRT](../global-state.md).
-
+// _set_new_handler1.cpp
#include
int handle_program_memory_depletion( size_t )
@@ -57,7 +55,9 @@ int main( void )
}
```
-You can save the function address that was last passed to the **_set_new_handler** function and reinstate it later:
+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).
+
+You can save the function address that was last passed to the **`_set_new_handler`** function and reinstate it later:
```cpp
_PNH old_handler = _set_new_handler( my_handler );
@@ -68,81 +68,109 @@ You can save the function address that was last passed to the **_set_new_handler
// . . .
```
-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:
+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`*.
-```cpp
-_set_new_mode(1);
-```
+If a user-defined `operator new` is provided, the new handler functions aren't automatically called on failure.
-early in your program or link with Newmode.obj.
+For more information, see [`new`](../../cpp/new-operator-cpp.md) and [`delete`](../../cpp/delete-operator-cpp.md) in the *C++ Language Reference*.
-If a user-defined `operator new` is provided, the new handler functions are not automatically called on failure.
-
-For more information, see [new](../../cpp/new-operator-cpp.md) and [delete](../../cpp/delete-operator-cpp.md) in the *C++ Language Reference*.
-
-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.
+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.
## Requirements
-|Routine|Required header|
-|-------------|---------------------|
-|**_set_new_handler**|\|
+| Function | Required header |
+|--|--|
+| **`_set_new_handler`** | `` |
For more compatibility information, see [Compatibility](../../c-runtime-library/compatibility.md).
## Example
-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.
+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.
```cpp
// crt_set_new_handler.cpp
-// compile with: /c
-#include
+// 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
+#include
#include
-#define BIG_NUMBER 0x1fffffff
-int coalesced = 0;
+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{};
-int CoalesceHeap()
-{
- coalesced = 1; // Flag RecurseAlloc to stop
- // do some work to free memory
- return 0;
-}
// Define a function to be called if new fails to allocate memory.
-int MyNewHandler( size_t size )
+int MyNewHandler(size_t /* unused */)
{
- printf("Allocation failed. Coalescing heap.\n");
-
- // Call a function to recover some heap space.
- return CoalesceHeap();
+ // 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;
}
-int RecurseAlloc() {
- int *pi = new int[BIG_NUMBER];
- if (!coalesced)
- RecurseAlloc();
- 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()
{
- // Set the failure handler for new to be MyNewHandler.
- _set_new_handler( MyNewHandler );
- RecurseAlloc();
+ try {
+ _set_new_handler(MyNewHandler); // Set handler for new.
+ RecurseAlloc();
+ }
+ catch (std::bad_alloc& ex) {
+ std::cerr << "bad_alloc caught: " << ex.what() << '\n';
+ }
}
-```
-
-```Output
-Allocation failed. Coalescing heap.
-This application has requested the Runtime to terminate it in an unusual way.
-Please contact the application's support team for more information.
+/* Output:
+MyNewHandler: Released reserved memory.
+MyNewHandler: Reserved memory exhausted.
+bad_alloc caught: bad allocation
+*/
```
## See also
-[Memory Allocation](../../c-runtime-library/memory-allocation.md)
-[calloc](calloc.md)
-[free](free.md)
-[realloc](realloc.md)
+[Memory allocation](../../c-runtime-library/memory-allocation.md)\
+[`calloc`](calloc.md)\
+[`free`](free.md)\
+[`realloc`](realloc.md)
diff --git a/docs/cpp/new-and-delete-operators.md b/docs/cpp/new-and-delete-operators.md
index e8e31c908e6..7561571216a 100644
--- a/docs/cpp/new-and-delete-operators.md
+++ b/docs/cpp/new-and-delete-operators.md
@@ -1,14 +1,12 @@
---
title: "new and delete operators"
description: "The C++ language new and delete operators allow control over allocation."
-ms.date: 07/07/2020
+ms.date: 05/21/2022
helpviewer_keywords: ["new keyword [C++]", "delete keyword [C++]"]
---
# `new` and `delete` operators
-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).
-
-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.
+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).
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).
@@ -20,9 +18,9 @@ The compiler translates a statement such as this one into a call to the function
char *pch = new char[BUFFER_SIZE];
```
-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.
+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.
-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.
+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).
The two scopes for **`operator new`** functions are described in the following table.
@@ -33,7 +31,7 @@ The two scopes for **`operator new`** functions are described in the following t
| **`::operator new`** | Global |
| *class-name* **`::operator new`** | Class |
-The first argument to **`operator new`** must be of type `size_t`, defined in \, and the return type is always **`void*`**.
+The first argument of **`operator new`** must be of type `size_t`, and the return type is always **`void*`**.
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.
@@ -94,24 +92,67 @@ int main()
}
```
+### Allocation failure behavior
+
+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.
+
+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).
+
+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).
+
### Handling insufficient memory
-Testing for failed memory allocation can be done as shown here:
+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:
+
+```cpp
+#include
+#include
+using namespace std;
+#define BIG_NUMBER 10000000000LL
+int main() {
+ try {
+ int *pI = new int[BIG_NUMBER];
+ }
+ catch (bad_alloc& ex) {
+ cout << "Caught bad_alloc: " << ex.what() << endl;
+ return -1;
+ }
+}
+```
+
+When you use the `nothrow` form of **`new`**, you can test for an allocation failure as shown in this sample:
+
+```cpp
+#include
+#include
+using namespace std;
+#define BIG_NUMBER 10000000000LL
+int main() {
+ int *pI = new(nothrow) int[BIG_NUMBER];
+ if ( pI == nullptr ) {
+ cout << "Insufficient memory" << endl;
+ return -1;
+ }
+}
+```
+
+You can test for a failed memory allocation when you've used *`nothrownew.obj`* file to replace global **`operator new`** as shown here:
```cpp
#include
+#include
using namespace std;
-#define BIG_NUMBER 100000000
+#define BIG_NUMBER 10000000000LL
int main() {
int *pI = new int[BIG_NUMBER];
- if( pI == 0x0 ) {
+ if ( !pI ) {
cout << "Insufficient memory" << endl;
return -1;
}
}
```
-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.
+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).
## The `delete` operator
diff --git a/docs/standard-library/new-operators.md b/docs/standard-library/new-operators.md
index ddd7a0a9292..0df7cbc0715 100644
--- a/docs/standard-library/new-operators.md
+++ b/docs/standard-library/new-operators.md
@@ -1,105 +1,105 @@
---
description: "Learn more about: operators and enums"
title: " operators and enums"
-ms.date: "11/04/2016"
+ms.date: 05/21/2022
f1_keywords: ["new/std::operator delete", "new/std::operator new"]
ms.assetid: d1af4b56-9a95-4c65-ab01-bf43e982c7bd
---
# `` operators and enums
-## enum align_val_t
+## `enum align_val_t`
```cpp
enum class align_val_t : size_t {};
```
-## operator delete
+## `operator delete`
-The function called by a delete expression to de-allocate storage for individual of objects.
+The function called by a `delete` expression to deallocate storage for individual objects.
```cpp
-void operator delete(void* ptr) throw();
-void operator delete(void *, void*) throw();
-void operator delete(void* ptr, const std::nothrow_t&) throw();
+void operator delete(void* ptr) noexcept;
+void operator delete(void *, void*) noexcept;
+void operator delete(void* ptr, const std::nothrow_t&) noexcept;
```
### Parameters
-*ptr*\
+*`ptr`*\
The pointer whose value is to be rendered invalid by the deletion.
### Remarks
-The first function is called by a delete expression to render the value of *ptr* invalid. The program can define a function with this function signature that replaces the default version defined by the C++ Standard Library. The required behavior is to accept a value of *ptr* that is null or that was returned by an earlier call to [operator new](../standard-library/new-operators.md#op_new)(**size_t**).
+The first function is called by a `delete` expression to render the value of *`ptr`* invalid. The program can define a function with this function signature that replaces the default version defined by the C++ Standard Library. The required behavior is to accept a value of *`ptr`* that's `nullptr` or that was returned by an earlier call to [`operator new`](../standard-library/new-operators.md#op_new).
-The default behavior for a null value of *ptr* is to do nothing. Any other value of *ptr* must be a value returned earlier by a call as previously described. The default behavior for such a nonnull value of *ptr* is to reclaim storage allocated by the earlier call. It is unspecified under what conditions part or all of such reclaimed storage is allocated by a subsequent call to `operator new`(**size_t**), or to any of `calloc`( **size_t**), `malloc`( **size_t**), or `realloc`( **`void`**\*, **size_t**).
+The default behavior for a `nullptr` value in *`ptr`* is to do nothing. Any other value of *`ptr`* must be a value returned earlier by a `new` call as previously described. The default behavior for a non-null value of *`ptr`* is to reclaim storage allocated by the earlier call. It's unspecified under what conditions part or all of such reclaimed storage is allocated by a subsequent call to `operator new`, or to any of the `calloc`, `malloc`, or `realloc` functions.
-The second function is called by a placement delete expression corresponding to a new expression of the form **`new`**( **std::size_t**). It does nothing.
+The second function is called by a placement `delete` expression corresponding to a `new` expression of the form `new( std::size_t )`. It does nothing.
-The third function is called by a placement delete expression corresponding to a new expression of the form **`new`**( **std::size_t**, **conststd::nothrow_t&**). The program can define a function with this function signature that replaces the default version defined by the C++ Standard Library. The required behavior is to accept a value of `ptr` that is null or that was returned by an earlier call to `operator new`( **size_t**). The default behavior is to evaluate **`delete`**(`ptr`).
+The third function is called by a placement `delete` expression corresponding to a `new` expression of the form `new( std::size_t, const std::nothrow_t& )`. The program can define a function with this function signature that replaces the default version defined by the C++ Standard Library. The required behavior is to accept a value of `ptr` that is `nullptr` or that was returned by an earlier call to `operator new`. The default behavior is to evaluate `delete( ptr )`.
### Example
-See [operator new](../standard-library/new-operators.md#op_new) for an example that use **operator delete**.
+See [`operator new`](../standard-library/new-operators.md#op_new) for an example that uses `operator delete`.
-## operator delete[]
+## `operator delete[]`
-The function called by a delete expression to deallocate storage for an array of objects.
+The function called by a `delete` expression to deallocate storage for an array of objects.
```cpp
-void operator delete[](void* ptr) throw();
-void operator delete[](void *, void*) throw();
-void operator delete[](void* ptr, const std::nothrow_t&) throw();
+void operator delete[](void* ptr) noexcept;
+void operator delete[](void *, void*) noexcept;
+void operator delete[](void* ptr, const std::nothrow_t&) noexcept;
```
### Parameters
-*ptr*\
+*`ptr`*\
The pointer whose value is to be rendered invalid by the deletion.
### Remarks
-The first function is called by an `delete[]` expression to render the value of *ptr* invalid. The function is replaceable because the program can define a function with this function signature that replaces the default version defined by the C++ Standard Library. The required behavior is to accept a value of *ptr* that is null or that was returned by an earlier call to [`operator new[]`](../standard-library/new-operators.md#op_new_arr)(**size_t**). The default behavior for a null value of *ptr* is to do nothing. Any other value of *ptr* must be a value returned earlier by a call as previously described. The default behavior for such a non-null value of *ptr* is to reclaim storage allocated by the earlier call. It is unspecified under what conditions part or all of such reclaimed storage is allocated by a subsequent call to [operator new](../standard-library/new-operators.md#op_new)(**size_t**), or to any of `calloc`(**size_t**), `malloc`(**size_t**), or `realloc`( **`void`**\*, **size_t**).
+The first function is called by an `delete[]` expression to render the value of *`ptr`* invalid. The function is replaceable because the program can define a function with this function signature that replaces the default version defined by the C++ Standard Library. The required behavior is to accept a value of *`ptr`* that is `nullptr` or that was returned by an earlier call to [`operator new[]`](../standard-library/new-operators.md#op_new_arr). The default behavior for a null value of *`ptr`* is to do nothing. Any other value of *`ptr`* must be a value returned earlier by a call as previously described. The default behavior for such a non-null value of *`ptr`* is to reclaim storage allocated by the earlier call. It's unspecified under what conditions part or all of such reclaimed storage is allocated by a subsequent call to [`operator new`](../standard-library/new-operators.md#op_new), or to any of the `calloc`, `malloc`, or `realloc` functions.
-The second function is called by a placement `delete[]` expression corresponding to a `new[]` expression of the form `new[]`(**std::size_t**). It does nothing.
+The second function is called by a placement `delete[]` expression corresponding to a `new[]` expression of the form `new[]( std::size_t )`. It does nothing.
-The third function is called by a placement delete expression corresponding to a `new[]` expression of the form `new[]`( **std::size_t**, **const std::nothrow_t&**). The program can define a function with this function signature that replaces the default version defined by the C++ Standard Library. The required behavior is to accept a value of *ptr* that is null or that was returned by an earlier call to operator `new[]`(**size_t**). The default behavior is to evaluate `delete[]`( `ptr`).
+The third function is called by a placement `delete[]` expression corresponding to a `new[]` expression of the form `new[]( std::size_t, const std::nothrow_t& )`. The program can define a function with this function signature that replaces the default version defined by the C++ Standard Library. The required behavior is to accept a value of *`ptr`* that is `nullptr` or that was returned by an earlier call to operator `new[]`. The default behavior is to evaluate `delete[]( ptr )`.
### Example
See [`operator new[]`](../standard-library/new-operators.md#op_new_arr) for examples of the use of `operator delete[]`.
-## operator new
+## `operator new`
The function called by a new-expression to allocate storage for individual objects.
```cpp
-void* operator new(std::size_t count) throw(bad_alloc);
-void* operator new(std::size_t count, const std::nothrow_t&) throw();
-void* operator new(std::size_t count, void* ptr) throw();
+void* operator new(std::size_t count);
+void* operator new(std::size_t count, const std::nothrow_t&) noexcept;
+void* operator new(std::size_t count, void* ptr) noexcept;
```
### Parameters
-*count*\
+*`count`*\
The number of bytes of storage to be allocated.
-*ptr*\
+*`ptr`*\
The pointer to be returned.
-### Return Value
+### Return value
-A pointer to the lowest byte address of the newly-allocated storage. Or *ptr*.
+A pointer to the lowest byte address of the newly allocated storage. Or *`ptr`*, if using the third form of the function.
### Remarks
-The first function is called by a new expression to allocate `count` bytes of storage suitably aligned to represent any object of that size. The program can define an alternate function with this function signature that replaces the default version defined by the C++ Standard Library and so is replaceable.
+The first function is called by a `new` expression to allocate `count` bytes of storage suitably aligned to represent any object of that size. This function is *replaceable*. It means the program can define an alternate function with this function signature that replaces the default version defined by the C++ Standard Library.
-The required behavior is to return a non-null pointer only if storage can be allocated as requested. Each such allocation yields a pointer to storage disjoint from any other allocated storage. The order and contiguity of storage allocated by successive calls is unspecified. The initial stored value is unspecified. The returned pointer points to the start (lowest byte address) of the allocated storage. If count is zero, the value returned does not compare equal to any other value returned by the function.
+The required behavior is to return a non-null pointer only if storage can be allocated as requested. Each such allocation yields a pointer to storage disjoint from any other allocated storage. The order and contiguity of storage allocated by successive calls is unspecified. The initial stored value is unspecified. The returned pointer points to the start (the lowest byte address) of the allocated storage. If *`count`* is zero, the value returned doesn't compare equal to any other value returned by the function.
-The default behavior is to execute a loop. Within the loop, the function first attempts to allocate the requested storage. Whether the attempt involves a call to `malloc`( **size_t**) is unspecified. If the attempt is successful, the function returns a pointer to the allocated storage. Otherwise, the function calls the designated [new handler](../standard-library/new-typedefs.md#new_handler). If the called function returns, the loop repeats. The loop terminates when an attempt to allocate the requested storage is successful or when a called function does not return.
+The default behavior is to execute a loop. Within the loop, the function first attempts to allocate the requested storage. Whether the attempt involves a call to `malloc` is unspecified. If the allocation attempt is successful, the function returns a pointer to the allocated storage. Otherwise, the function calls the designated function of type [`new_handler`](../standard-library/new-typedefs.md#new_handler). If the called function returns, the loop repeats. The loop terminates when an attempt to allocate the requested storage is successful or when a called function doesn't return.
-The required behavior of a new handler is to perform one of the following operations:
+The required behavior of a function of type `new_handler` is to perform one of the following operations:
- Make more storage available for allocation and then return.
@@ -107,19 +107,23 @@ The required behavior of a new handler is to perform one of the following operat
- Throw an object of type `bad_alloc`.
-The default behavior of a [new handler](../standard-library/new-typedefs.md#new_handler) is to throw an object of type `bad_alloc`. A null pointer designates the default new handler.
+The default behavior of a [`new_handler`](../standard-library/new-typedefs.md#new_handler) function is to throw an object of type `bad_alloc`. A `nullptr` value designates the default `new_handler` function.
-The order and contiguity of storage allocated by successive calls to `operator new`(**size_t**) is unspecified, as are the initial values stored there.
+The order and contiguity of storage allocated by successive calls to `operator new` is unspecified, as are the initial values stored there.
-The second function is called by a placement new expression to allocate `count` bytes of storage suitably aligned to represent any object of that size. The program can define an alternate function with this function signature that replaces the default version defined by the C++ Standard Library and so is replaceable.
+To free storage allocated by the first form of `operator new`, call [`operator delete`](../standard-library/new-operators.md#op_delete).
-The default behavior is to return `operator new`(`count`) if that function succeeds. Otherwise, it returns a null pointer.
+The second function is called by a placement `new` expression to allocate *`count`* bytes of storage suitably aligned to represent any object of that size. This function is *replaceable*. It means the program can define an alternate function with this function signature that replaces the default version defined by the C++ Standard Library.
-The third function is called by a placement **`new`** expression, of the form `new ( args ) T`. Here, *args* consists of a single object pointer. This can be useful for constructing an object at a known address. The function returns *ptr*.
+The default behavior is to return `operator new( count )` if that function succeeds. Otherwise, it returns `nullptr`.
-To free storage allocated by **operator new**, call [operator delete](../standard-library/new-operators.md#op_delete).
+To free storage allocated by the second form of `operator new` (that is, if it didn't return `nullptr`), call [`operator delete`](../standard-library/new-operators.md#op_delete).
-For information on throwing or non-throwing behavior of new, see [The new and delete Operators](../cpp/new-and-delete-operators.md).
+The third function is called by a non-allocating placement `new` expression, of the form `new ( ptr ) T`. Here, *`ptr`* consists of a single object pointer. It can be useful for constructing an object at a known address. The function returns *`ptr`*. You must call the destructor explicitly on this object.
+
+If you call non-allocating placement `new`, don't call `delete`. Instead, call the deallocator for the memory you provided, if necessary, after you call the destructor for the object.
+
+For information on throwing or non-throwing behavior of `new`, see [The `new` and `delete` operators](../cpp/new-and-delete-operators.md).
### Example
@@ -131,77 +135,71 @@ For information on throwing or non-throwing behavior of new, see [The new and de
using namespace std;
-class MyClass
-{
+class MyClass {
+ int member{ 0 };
public:
- MyClass( )
- {
- cout << "Construction MyClass." << this << endl;
- };
-
- ~MyClass( )
- {
- imember = 0; cout << "Destructing MyClass." << this << endl;
- };
- int imember;
+ MyClass() {
+ cout << "MyClass at 0x" << this << " constructed.\n";
+ };
+
+ ~MyClass() {
+ cout << "MyClass at 0x" << this << " destroyed.\n";
+ };
};
int main( )
{
- // The first form of new delete
- MyClass* fPtr = new MyClass;
- delete fPtr;
-
- // The second form of new delete
- MyClass* fPtr2 = new( nothrow ) MyClass;
- delete fPtr2;
-
- // The third form of new delete
- char x[sizeof( MyClass )];
- MyClass* fPtr3 = new( &x[0] ) MyClass;
- fPtr3 -> ~MyClass();
- cout << "The address of x[0] is : " << ( void* )&x[0] << endl;
+ // The first form of new / delete
+ MyClass* fPtr1 = new MyClass;
+ delete fPtr1;
+
+ // The second form (fail returns nullptr) of new / delete
+ MyClass* fPtr2 = new(nothrow) MyClass[2];
+ if (fPtr2)
+ delete fPtr2;
+
+ // The third form (non-allocating placement) of new / delete
+ char x[sizeof(MyClass)]; // x is automatic
+ MyClass* fPtr3 = new(&x[0]) MyClass;
+ fPtr3->~MyClass(); // Requires explicit destructor call
+ // no delete because x is on the stack
}
```
-## operator new[]
+## `operator new[]`
The allocation function called by a new expression to allocate storage for an array of objects.
```cpp
-void* operator new[](std::size_t count) throw(std::bad_alloc);
-void* operator new[](std::size_t count, const std::nothrow_t&) throw();
-void* operator new[](std::size_t count, void* ptr) throw();
+void* operator new[](std::size_t count);
+void* operator new[](std::size_t count, const std::nothrow_t&) noexcept;
+void* operator new[](std::size_t count, void* ptr) noexcept;
```
### Parameters
-*count*\
+*`count`*\
The number of bytes of storage to be allocated for the array object.
-*ptr*\
+*`ptr`*\
The pointer to be returned.
-### Return Value
+### Return value
-A pointer to the lowest byte address of the newly-allocated storage. Or *ptr*.
+A pointer to the lowest byte address of the newly allocated storage. Or *`ptr`*, when the third form is used.
### Remarks
-The first function is called by a `new[]` expression to allocate `count` bytes of storage suitably aligned to represent any array object of that size or smaller. The program can define a function with this function signature that replaces the default version defined by the C++ Standard Library. The required behavior is the same as for [operator new](../standard-library/new-operators.md#op_new)(**size_t**). The default behavior is to return `operator new`( `count`).
-
-The second function is called by a placement `new[]` expression to allocate `count` bytes of storage suitably aligned to represent any array object of that size. The program can define a function with this function signature that replaces the default version defined by the C++ Standard Library. The default behavior is to return **operatornew**(`count`) if that function succeeds. Otherwise, it returns a null pointer.
+The first function is called by a `new[]` expression to allocate *`count`* bytes of storage suitably aligned to represent any array object of that size or smaller. The program can define a function with this function signature that replaces the default version defined by the C++ Standard Library. The required behavior is the same as for [`operator new`](../standard-library/new-operators.md#op_new). The default behavior is to return `operator new( count )` if it succeeds. Otherwise, it throws a `std::bad_alloc` exception (or an exception derived from `std::bad_alloc`). To free storage allocated by this form of `operator new[]`, call [`operator delete[]`](../standard-library/new-operators.md#op_delete_arr).
-The third function is called by a placement `new[]` expression, of the form **`new`** ( *args*) **T**[ **N**]. Here, *args* consists of a single object pointer. The function returns `ptr`.
+The second function is called by a placement `new[]` expression to allocate *`count`* bytes of storage suitably aligned to represent any array object of that size. The program can define a function with this function signature that replaces the default version defined by the C++ Standard Library. The default behavior is to return `operator new( count )` if that function succeeds. Otherwise, it returns `nullptr`. To free storage allocated by this form of `operator new[]`, call `operator delete[]`. For more information on the throwing or non-throwing behavior of `new`, see [The `new` and `delete` operators](../cpp/new-and-delete-operators.md).
-To free storage allocated by `operator new[]`, call [`operator delete[]`](../standard-library/new-operators.md#op_delete_arr).
-
-For information on throwing or nonthrowing behavior of new, see [The new and delete Operators](../cpp/new-and-delete-operators.md).
+The third function is called by a non-allocating placement `new[]` expression, of the form `new( ptr ) T[ N ]`. This form doesn't allocate memory. It constructs the objects in the memory passed in through the *`ptr`* parameter. The function returns *`ptr`*. You must call the destructor explicitly for each object created. You're responsible for providing sufficient memory for *`ptr`*. Don't invoke `delete[]` on the value returned by the `new` expression. Instead, deallocate *`ptr`*, if necessary, after you call the destructors.
### Example
```cpp
-// new_op_alloc.cpp
+// new_op_array.cpp
// compile with: /EHsc
#include
#include
@@ -209,32 +207,34 @@ For information on throwing or nonthrowing behavior of new, see [The new and del
using namespace std;
class MyClass {
+ int member{ 0 };
public:
- MyClass() {
- cout << "Construction MyClass." << this << endl;
- };
-
- ~MyClass() {
- imember = 0; cout << "Destructing MyClass." << this << endl;
- };
- int imember;
+ MyClass() {
+ cout << "MyClass at 0x" << this << " constructed.\n";
+ };
+
+ ~MyClass() {
+ cout << "MyClass at 0x" << this << " destroyed.\n";
+ };
};
int main() {
- // The first form of new delete
- MyClass* fPtr = new MyClass[2];
- delete[ ] fPtr;
-
- // The second form of new delete
- char x[2 * sizeof( MyClass ) + sizeof(int)];
-
- MyClass* fPtr2 = new( &x[0] ) MyClass[2];
- fPtr2[1].~MyClass();
- fPtr2[0].~MyClass();
- cout << "The address of x[0] is : " << ( void* )&x[0] << endl;
-
- // The third form of new delete
- MyClass* fPtr3 = new( nothrow ) MyClass[2];
- delete[ ] fPtr3;
+ // The first form of array new / delete
+ MyClass* fPtr1 = new MyClass[2];
+ delete[] fPtr1;
+
+ // The second form (fail returns nullptr) of array new / delete
+ MyClass* fPtr2 = new(nothrow) MyClass[2];
+ if (fPtr2)
+ delete[] fPtr2;
+
+ // The third form (non-allocating placement) of array new / delete
+ char x[2 * sizeof(MyClass) + sizeof(int)]; // x is automatic
+
+ MyClass* fPtr3 = new(&x[0]) MyClass[2];
+ fPtr3[1].~MyClass(); // Requires explicit destructor calls
+ fPtr3[0].~MyClass(); // Recommended in reverse construction order
+ // Don't delete[] fPtr3 here.
+ // delete[] &x[0] not required because x is on the stack
}
```
diff --git a/docs/standard-library/new-typedefs.md b/docs/standard-library/new-typedefs.md
index 255ce65355d..6dd94c34073 100644
--- a/docs/standard-library/new-typedefs.md
+++ b/docs/standard-library/new-typedefs.md
@@ -1,13 +1,13 @@
---
description: "Learn more about: typedefs"
title: " typedefs"
-ms.date: "11/04/2016"
+ms.date: 05/27/2022
f1_keywords: ["new/std::new_handler"]
ms.assetid: aef01de1-06b5-4b6c-aebc-2c9f423d7e47
---
# `` typedefs
-## hardware_constructive_interference_size
+## `hardware_constructive_interference_size`
```cpp
inline constexpr size_t hardware_constructive_interference_size = implementation-defined;
@@ -15,7 +15,7 @@ inline constexpr size_t hardware_constructive_interference_size = implementation
### Remarks
-This number is the maximum recommended size of contiguous memory occupied by two objects accessed with temporal locality by concurrent threads. It shall be at least `alignof(max_align_t)`.
+This number is the maximum recommended size of contiguous memory occupied by two objects accessed with temporal locality by concurrent threads. It must be at least `alignof(max_align_t)`.
### Example
@@ -34,7 +34,7 @@ struct kennel {
static_assert(sizeof(together) <= hardware_constructive_interference_size);
```
-## hardware_destructive_interference_size
+## `hardware_destructive_interference_size`
```cpp
inline constexpr size_t hardware_destructive_interference_size = implementation-defined;
@@ -42,7 +42,7 @@ inline constexpr size_t hardware_destructive_interference_size = implementation-
### Remarks
-This number is the minimum recommended offset between two concurrently-accessed objects to avoid additional performance degradation due to contention introduced by the implementation. It shall be at least `alignof(max_align_t)`.
+This number is the minimum recommended offset between two concurrently accessed objects to avoid performance degradation due to contention introduced by the implementation. It must be at least `alignof(max_align_t)`.
### Example
@@ -53,9 +53,9 @@ struct keep_apart {
};
```
-## new_handler
+## `new_handler`
-The type points to a function suitable for use as a new handler.
+The `new_handler` type points to a function suitable for use as a *`new handler`*, a function that can reclaim or release memory.
```cpp
typedef void (*new_handler)();
@@ -63,8 +63,8 @@ typedef void (*new_handler)();
### Remarks
-This type of handler function is called by **operator new** or `operator new[]` when they cannot satisfy a request for additional storage.
+When of function of this type is set by [`std::set_new_handler`](../standard-library/new-functions.md#set_new_handler), the function is called by `operator new` or `operator new[]` when they can't satisfy a request for more storage.
### Example
-See [set_new_handler](../standard-library/new-functions.md#set_new_handler) for an example using `new_handler` as a return value.
+For an example that uses `new_handler` as a return value, see [`set_new_handler`](../standard-library/new-functions.md#set_new_handler).