You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

std::make_shared与类专属operator new兼容吗?如何追踪MyClass内存?

解决std::make_shared无法追踪类专属内存分配的问题

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 10:12:27