C++如何重写全局new和delete操作符

星晨君_5434

星晨君_5434

2026-10-23

696人浏览

原创

c++oding="utf-8" ?>

重写全局operator new和delete必须成对提供,含单对象、数组、对齐版本;均需noexcept,用malloc/free避免递归;禁止依赖未初始化全局对象,确保全生命周期安全。

c++如何重写全局new和delete操作符

重写全局operator new和operator delete必须成对提供

只重载operator new而不提供对应operator delete,会导致new失败时调用默认delete(可能崩溃或未定义行为),尤其在构造函数抛异常时必踩坑。C++标准要求:每个可抛异常的operator new都应有匹配的operator delete,否则内存泄漏或UB风险极高。

最简可行写法如下:

void* operator new(std::size_t size) noexcept {
    void* ptr = std::malloc(size);
    if (!ptr) throw std::bad_alloc{};
    return ptr;
}
<p>void operator delete(void* ptr) noexcept {
std::free(ptr);
}</p>
  • noexcept是关键——与系统默认版本签名一致,否则链接失败
  • 必须用std::malloc/std::free而非new/delete,避免递归调用
  • 不要在operator new里直接throw std::bad_alloc;先尝试分配,失败再抛,否则绕过set_new_handler

处理数组版本operator new[]和operator delete[]不能省略

哪怕你从不写new int[10],STL容器(如std::vector)内部会调用它们。漏掉数组版本,轻则内存泄漏,重则释放时crash(因为delete[]可能传入错误地址或元数据)。

数组版必须严格对应:

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
void* operator new[](std::size_t size) noexcept {
    return operator new(size); // 复用单对象版本即可
}
<p>void operator delete[](void* ptr) noexcept {
operator delete(ptr); // 必须调用单对象delete,不是free!
}</p>
  • 数组new[]返回的指针,delete[]必须交给operator delete[],不能交给operator delete
  • 但operator delete[]内部可以复用operator delete逻辑——前提是你的operator delete能安全处理任意指针(包括空指针)
  • 别试图在new[]里额外分配长度头信息:C++不保证delete[]会传回原地址,且标准库可能自己管理

带std::align_val_t的对齐版本必须显式声明(C++17起)

如果代码用了alignas(64)或new(align_val_t{64}),而你没提供对齐版本,链接器直接报错:undefined reference to operator new(unsigned long, std::align_val_t)。即使没显式用对齐,某些STL实现(如libc++)也会在内部调用它。

补全对齐版本只需加参数:

void* operator new(std::size_t size, std::align_val_t align) noexcept {
    return std::aligned_alloc(static_cast<:size_t>(align), size);
}
<p>void operator delete(void* ptr, std::align_val_t) noexcept {
std::free(ptr);
}</p></:size_t>
  • std::aligned_alloc要求size是align的整数倍,实际使用中建议向上对齐(如用std::ceil或位运算)
  • 注意operator delete带align_val_t参数时,必须也声明对应版本,否则delete时链接失败
  • Windows下_aligned_malloc/_aligned_free替代std::aligned_alloc(后者在MSVC 2019前不支持)

替换全局操作符后,静态/线程局部对象的构造顺序容易出问题

全局operator new在main()之前就生效,但此时std::malloc等基础设施可能未初始化(尤其在动态库中)。更危险的是:如果自定义new依赖某个全局对象(比如日志器、内存池),而该对象自身又用new分配——必然死锁或访问未初始化内存。

  • 绝对不要在operator new里调用任何可能触发new的代码(包括std::cout、std::string构造、STL容器)
  • 调试时可用malloc + write(2)打印日志,绕过C++运行时依赖
  • 若需线程安全,用std::atomic_flag或pthread_mutex_t(确保其静态初始化不依赖new)
  • 测试务必覆盖:全局对象构造、static局部变量首次进入、atexit注册函数执行阶段

真正难的从来不是写几行重载函数,而是确保它在程序生命周期每个角落都安全——尤其是那些你根本没意识到正在调用它的时刻。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2248

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1019

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

447

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

327

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

426

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

580

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1409

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1217

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
尚学堂ios初级视频教程
尚学堂ios初级视频教程

共77课时 | 21.3万人学习

C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习