重定义new和delete运算符
重定义new和delete运算符
看起来你已经迈出了用自定义分配器重定义全局new/delete运算符的关键一步!先帮你梳理下当前实现的要点,以及在多翻译单元的C++项目里必须注意的几个细节:
首先贴出你当前在memops.hpp中的实现:
#pragma once #include "../lib/mem.h" void* operator new(size_t size) { return __mem_alloc(size); } void operator delete(void *ptr) { __mem_free(ptr); } void* operator new[](size_t size) { return __mem_alloc(size); } void operator delete[](void *ptr) { __mem_free(ptr); }
核心注意事项
避免多定义链接错误
你现在把实现直接放在头文件里,一旦多个.cpp文件包含这个头,就会触发“multiple definition”链接错误。正确的做法是把声明放在头文件,实现移到单独的.cpp文件:
头文件memops.hpp只留声明:#pragma once #include "../lib/mem.h" void* operator new(size_t size); void operator delete(void *ptr); void* operator new[](size_t size); void operator delete[](void *ptr);然后新建
memops.cpp放实现:#include "memops.hpp" #include <stdexcept> void* operator new(size_t size) { void* ptr = __mem_alloc(size); if (!ptr) { throw std::bad_alloc(); } return ptr; } void operator delete(void *ptr) { if (ptr) { __mem_free(ptr); } } void* operator new[](size_t size) { void* ptr = __mem_alloc(size); if (!ptr) { throw std::bad_alloc(); } return ptr; } void operator delete[](void *ptr) { if (ptr) { __mem_free(ptr); } }符合标准的异常行为
标准C++要求普通的operator new在分配失败时必须抛出std::bad_alloc异常,直接返回nullptr会导致未定义行为。上面的实现已经补上了异常抛出逻辑;如果你的项目需要不抛异常的版本,可以额外实现nothrow重载:void* operator new(size_t size, const std::nothrow_t&) noexcept { return __mem_alloc(size); } void operator delete(void *ptr, const std::nothrow_t&) noexcept { if (ptr) { __mem_free(ptr); } }数组分配的特殊处理
你现在对单个对象和数组的分配用了相同的__mem_alloc,如果你的自定义分配器不需要区分两者(比如不需要额外存储数组长度),那没问题;但如果__mem_alloc需要针对数组做特殊处理,记得在operator new[]里调整逻辑。线程安全检查
如果你的项目是多线程的,一定要确保__mem_alloc和__mem_free是线程安全的,否则会出现内存竞争、数据损坏等问题。空指针保护
在operator delete里加个空指针判断是个好习惯,避免__mem_free处理空指针时可能的崩溃(虽然很多分配器本身会处理空指针,但显式判断更稳妥)。
备注:内容来源于stack exchange,提问作者mdjukan
相关产品推荐
相关产品推荐

