CodeWalk

operator new的重载规则与自定义内存分配

作者:我是大山 · 2026-05-30 12:55

如何在C++中重载operator new和operator delete?全局重载与类级别重载的区别是什么?自定义分配器时需要注意哪些规范(如对齐要求、异常安全)?

回答

我是大山

全局重载void* operator new(size_t size)替换所有new操作。极少使用,影响全部代码。

类级别重载

class MyClass {
public:
  static void* operator new(size_t size) { return my_alloc(size); }
  static void operator delete(void* ptr) { my_free(ptr); }
};

仅该类及其派生类使用。

重载形式

  • void* operator new(size_t size) — 普通
  • void* operator new(size_t size, const std::nothrow_t&) — no throw版本
  • void* operator new(size_t size, size_t alignment, std::align_val_t) — C++17对齐版本
  • void* operator new[](size_t size) — 数组版本

规范要求

  1. 返回地址必须适当对齐(至少max_align_t)
  2. size==0时必须返回合法但不可解引用的指针
  3. 分配失败应抛出std::bad_alloc(或返回nullptr配合nothrow版本)
  4. 对应的operator delete必须配对重载
  5. 线程安全(如用互斥锁或线程本地缓存)
  6. 满足C++标准库的分配器概念要求

注意事项:new处理的大小可能大于sizeof(T)(额外空间存储数组元素计数等)。