std::make_shared与类专属operator new兼容吗?如何追踪MyClass内存?
std::make_shared为了内存效率,会一次性分配对象实例与shared_ptr控制块的内存,直接调用全局::operator new,不会触发MyClass的专属operator new/delete,导致Tracker无法捕获内存操作。以下是几种无需修改全局new的解决方案:
方案1:自定义分配器配合std::allocate_shared
实现一个封装全局内存操作的追踪分配器,用std::allocate_shared替代std::make_shared,让内存分配/释放走自定义分配器逻辑,从而触发Tracker。
#include <memory> template <typename T> struct TrackingAllocator { using value_type = T; TrackingAllocator() = default; template <typename U> TrackingAllocator(const TrackingAllocator<U>&) noexcept {} T* allocate(std::size_t n) { const std::size_t sz = n * sizeof(T); Tracker::allocated(sz); return static_cast<T*>(::operator new(sz)); } void deallocate(T* ptr, std::size_t n) noexcept { const std::size_t sz = n * sizeof(T); Tracker::deallocated(sz); ::operator delete(ptr); } }; // 分配器等价性判断 template <typename T, typename U> bool operator==(const TrackingAllocator<T>&, const TrackingAllocator<U>&) noexcept { return true; } template <typename T, typename U> bool operator!=(const TrackingAllocator<T>&, const TrackingAllocator<U>&) noexcept { return false; } // 使用示例 auto sp = std::allocate_shared<MyClass>(TrackingAllocator<MyClass>());
该方案无需修改MyClass现有代码,仅需替换创建方式即可完整追踪内存操作。
方案2:封装工厂函数统一创建路径
给MyClass私有化构造函数,提供静态工厂函数强制所有实例创建走能触发Tracker的路径,避免外部直接使用make_shared或裸new。
修改后的MyClass:
class MyClass { private: // 私有化构造函数,限制创建方式 MyClass() = default; public: // 保留原有专属operator new/delete static void operator delete(void * ptr, std::size_t sz) { Tracker::deallocated(sz); ::operator delete(ptr); } static void operator delete[](void * ptr, std::size_t sz) { Tracker::deallocated(sz); ::operator delete[](ptr); } static void * operator new(std::size_t sz) { Tracker::allocated(sz); return ::operator new(sz); } static void * operator new[](std::size_t sz) { Tracker::allocated(sz); return ::operator new[](sz); } // 工厂函数:返回shared_ptr,触发类专属内存操作 static std::shared_ptr<MyClass> create() { return std::shared_ptr<MyClass>(new MyClass()); } };
使用方式:
auto sp = MyClass::create();
此方案从源头控制实例创建,确保所有内存操作都被Tracker捕获,同时避免误用make_shared。
内容的提问来源于stack exchange,提问作者calvin
相关产品推荐
相关产品推荐

