C++ 参考手册
- C++11
- C++14
- C++17
- C++20
- C++ 编译器支持情况表
- 独立与宿主实现
- C++ 语言
- C++ 关键词
- 预处理器
- C++ 标准库头文件
- 具名要求
- 功能特性测试 (C++20)
- 工具库
- 类型支持(基本类型、RTTI、类型特性)
- 概念库 (C++20)
- 错误处理
- 动态内存管理
- std::unique_ptr
- std::scoped_allocator_adaptor
- std::auto_ptr
- std::destroy_at
- std::destroy
- std::destroy_n
- std::uninitialized_move
- std::uninitialized_value_construct
- std::owner_less
- std::shared_ptr
- std::to_address
- std::assume_aligned
- std::make_obj_using_allocator
- C 内存管理库
- 低层内存管理
- operator delete, operator delete[]
- std::align_val_t
- std::bad_alloc
- std::bad_array_new_length
- operator new, operator new[]
- std::addressof
- std::allocator_traits
- std::default_delete
- std::allocator_arg_t
- std::allocator_arg
- std::weak_ptr
- std::enable_shared_from_this
- std::bad_weak_ptr
- std::pmr::memory_resource
- std::allocator
- std::pointer_traits
- std::uses_allocator
- std::uses_allocator_construction_args
- std::uninitialized_construct_using_allocator
- std::pmr::polymorphic_allocator
- std::pmr::get_default_resource
- std::pmr::set_default_resource
- std::pmr::new_delete_resource
- std::pmr::null_memory_resource
- std::pmr::synchronized_pool_resource
- std::pmr::unsynchronized_pool_resource
- std::pmr::monotonic_buffer_resource
- std::pmr::pool_options
- std::raw_storage_iterator
- std::get_temporary_buffer
- std::return_temporary_buffer
- std::uninitialized_copy
- std::uninitialized_fill
- std::uninitialized_default_construct
- std::uninitialized_copy_n
- std::uninitialized_fill_n
- std::uninitialized_move_n
- std::uninitialized_default_construct_n
- std::uninitialized_value_construct_n
- std::construct_at
- std::align
- 注释
- 日期和时间工具
- 字符串库
- 容器库
- 迭代器库
- 范围库 (C++20)
- 算法库
- 数值库
- 输入/输出库
- 文件系统库
- 本地化库
- 正则表达式库
- 原子操作库
- 线程支持库
- 实验性 C++ 特性
- 有用的资源
- 索引
- std 符号索引
- 协程支持 (C++20)
- C++ 关键词
operator new, operator new[]
[[nodiscard]]
noexcept |
(C++11 起) |
[[nodiscard]] |
(C++20 起) |
std::align_val_t al, const std::nothrow_t&);
std::align_val_t al, const std::nothrow_t&);
noexcept |
(C++11 起) |
[[nodiscard]] |
(C++20 起) |
std::align_val_t al, user-defined-args... );
std::align_val_t al, user-defined-args... );
std::align_val_t al, user-defined-args... );
std::align_val_t al, user-defined-args... );
分配请求数量的字节。这些分配函数为 new 表达式所调用,以分配将被初始化的对象所在的内存。亦可用常规函数调用语法调用它们。
count
字节。失败情况下,标准库实现调用 std::get_new_handler 所返回的函数指针,并重复尝试分配,直到 new 处理函数不返回或成为空指针,在该时刻抛出 std::bad_alloc 。要求此函数返回指向拥有请求大小的对象的适当对齐的指针。__STDCPP_DEFAULT_NEW_ALIGNMENT__
时为 new[] 表达式的不抛出数组形式所调用。标准库实现调用版本 (4) 并在失败时不传播异常而抛出空指针。__STDCPP_DEFAULT_NEW_ALIGNMENT__
。若定义类特定版本( (15) 或 (17) ),则调用之。若既不提供类特定版本又不提供具对齐布置形式(此形式),则替而查找无对齐布置形式 (11) 。__STDCPP_DEFAULT_NEW_ALIGNMENT__
。若定义类特定版本((16) 或 (18) ),则调用之。若既不提供类特定版本又不提供具对齐布置形式(此形式),则替而查找无对齐布置形式 (12) 。__STDCPP_DEFAULT_NEW_ALIGNMENT__
。若不提供此重载,但提供了无对齐成员形式 (15) ,则调用无对齐成员重载。__STDCPP_DEFAULT_NEW_ALIGNMENT__
。若不提供此重载,但提供了无对齐成员形式 (16) ,则调用无对齐成员重载。__STDCPP_DEFAULT_NEW_ALIGNMENT__
。若不提供此重载,但提供了无对齐成员形式 (19) ,则调用无对齐成员重载。__STDCPP_DEFAULT_NEW_ALIGNMENT__
。若不提供此重载,但提供了无对齐成员形式 (20) ,则调用无对齐成员重载。参数
count | - | 要分配的字节数 |
ptr | - | 指向要初始化的对象所在的内存区域的指针 |
tag | - | 用于选择不抛出重载的消歧义标签 |
al | - | 使用的对齐。若此非有效对齐值,则行为未定义 |
返回值
size
大小的适当对齐的内存size
大小的适当对齐的内存,或在失败时为空指针ptr
异常
全局替换
版本 (1-4) 在每个翻译单元隐式声明,即使不包含 <new>
头文件。版本 (1-8) 是可替换的:定义于程序任何位置,在任何源文件的用户提供的拥有相同签名的非成员函数,会替换默认版本。其声明不必可见。
若程序中为任何可替换分配函数提供多于一个替换版本,或若替换定义带 inline
指定符,则行为未定义。若替换定义于异于全局命名空间的命名空间中,或它定义为在全局作用域的 static 函数,则程序为病式。
nothrow 版本的标准库实现 (5-8) 直接调用对应的抛出版本 (1-4) 。抛出的数组版本的标准库实现 (2,4) 直接调用对应的单对象版本 (1,3) 。故而,替换抛出单对象分配函数足以处理所有分配。 |
(C++11 起) |
#include <cstdio> #include <cstdlib> // 函数最小集的替换: void* operator new(std::size_t sz) { std::printf("global op new called, size = %zu\n",sz); void *ptr = std::malloc(sz); if (ptr) return ptr; else throw std::bad_alloc{}; } void operator delete(void* ptr) noexcept { std::puts("global op delete called"); std::free(ptr); } int main() { int* p1 = new int; delete p1; int* p2 = new int[10]; // C++11 中保证调用替换者 delete[] p2; }
可能的输出:
global op new called, size = 4 global op delete called global op new called, size = 40 global op delete called
operator new
与 operator new[]
带额外用户定义参数的重载(“布置形式”,版本 (11-14) )可以照常声明于全局作用于,而且为匹配的 new 表达式的布置形式所调用。
标准库的 operator new 的不分配布置形式 (9-10) 不能被替换,而且只若布置 new 表达式不使用 ::new
语法才能自定义,通过提供类特定的带匹配签名的布置 new (19,20) : void* T::operator new(size_t, void*)
或 void* T::operator new[](size_t, void*)
。
布置形式 |
(C++14 起) |
类特定重载
单对象和数组分配函数都可以定义为类的公开静态成员函数(版本 (15-18) 。若定义,则 new 表达式调用这些函数,以分配此类单个对象或数组的内存,除非 new 表达式使用 ::new
形式,这跳过类作用域查找。关键词 static
对这些函数可选:不管是否使用,分配函数都是静态成员函数。
new 表达式首先在类作用域中查找适当的函数名,然后在全局作用域查找。注意,同每个名称查找规则,就试图分配此类对象的 new 表达式而言,任何声明于类作用域的分配函数隐藏所有全局分配函数。
在分配对齐超出 |
(C++17 起) |
#include <iostream> // 类特定分配函数 struct X { static void* operator new(std::size_t sz) { std::cout << "custom new for size " << sz << '\n'; return ::operator new(sz); } static void* operator new[](std::size_t sz) { std::cout << "custom new for size " << sz << '\n'; return ::operator new(sz); } }; int main() { X* p1 = new X; delete p1; X* p2 = new X[10]; delete[] p2; }
可能的输出:
custom new for size 1 custom new for size 10
operator new
与 operator new[]
带额外用户定义参数(“布置形式”)的重载,亦可定义为类成员 (19-22) 。在拥有匹配签名的布置 new 表达式查找要调用的对应分配函数时,查找在检验全局作用域前,从类作用域开始,而若提供了类特定的布置 new 则调用它。
在分配对齐超出 |
(C++17 起) |
#include <stdexcept> #include <iostream> struct X { X() { throw std::runtime_error(""); } // 自定义布置 new static void* operator new(std::size_t sz, bool b) { std::cout << "custom placement new called, b = " << b << '\n'; return ::operator new(sz); } // 自定义布置 delete static void operator delete(void* ptr, bool b) { std::cout << "custom placement delete called, b = " << b << '\n'; ::operator delete(ptr); } }; int main() { try { X* p1 = new (true) X; } catch(const std::exception&) { } }
输出:
custom placement new called, b = 1 custom placement delete called, b = 1
若类级别的 operator new
是模板函数,则它必须拥有返回类型 void*
,第一参数类型 std::size_t
,且它必须拥有二个或更多参数。换言之,仅布置形式能是模板。
注解
尽管不分配布置 new (9,10) 不能被替换,亦可在上面描述的类作用域定义拥有相同签名的函数。而且,像是布置 new 但接受非 void 指针类型作为第二参数的全局重载是的受到允许的,故意图确保调用真的布置 new 的代码(例如 std::allocator::construct )必须使用 ::new
并将指针转型到 void*
。
要求下列函数是线程安全的:
对这些分配或解分配特定存储单元的函数调用以单独全序出现,并且在此顺序中,每个解分配调用先发生于下个分配(若存在)。 |
(C++11 起) |
operator new
的库版本是否产生任何对 std::malloc 或 std::aligned_alloc (C++17 起) 的调用是未指定的。
示例
本节未完成 原因:暂无示例 |
参阅
解分配函数 (函数) | |
(C++11) |
获得当前的 new 处理函数 (函数) |
注册一个 new 处理函数 (函数) | |
(C++17 中弃用)(C++20 中移除) |
获得未初始化存储 (函数模板) |
分配内存 (函数) | |
(C++17) |
分配对齐的内存 (函数) |
引用
- C++11 standard (ISO/IEC 14882:2011):
- 18.6 Dynamic memory management [support.dynamic]