MST

星途 面试题库

面试题:C++中std::shared_ptr自定义分配器复杂场景应用

假设有一个分布式系统,在不同节点上的对象需要通过`std::shared_ptr`管理内存,并且要使用自定义分配器来适配不同节点的内存特性(例如,某些节点内存有限,某些节点需要特殊的内存对齐)。请设计一个通用的`std::shared_ptr`自定义分配器框架,使其能够适应这种复杂场景,描述设计思路并给出关键的代码结构(不需要完整实现所有细节,但要涵盖核心设计和接口)。
50.1万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 定义基础分配器接口:创建一个抽象基类,作为所有具体分配器的接口,其中包含allocatedeallocate等必要的内存管理函数。
  2. 具体分配器实现:针对不同节点的内存特性,实现具体的分配器,继承自上述基类。例如,为内存有限的节点实现一个限制分配大小的分配器,为需要特殊内存对齐的节点实现具有相应对齐功能的分配器。
  3. 共享指针自定义分配器封装:创建一个通用的自定义分配器模板类,它接受一个具体分配器类型作为模板参数,并将内存管理操作转发给具体分配器对象。
  4. 使用std::shared_ptr:使用这个自定义分配器模板类来实例化std::shared_ptr,从而使共享指针能使用不同的自定义分配器。

关键代码结构

// 1. 基础分配器接口
class BaseAllocator {
public:
    virtual void* allocate(size_t size) = 0;
    virtual void deallocate(void* ptr, size_t size) = 0;
    virtual ~BaseAllocator() = default;
};

// 2. 具体分配器实现示例:内存有限分配器
class LimitedMemoryAllocator : public BaseAllocator {
private:
    size_t maxMemory;
    size_t usedMemory;
public:
    LimitedMemoryAllocator(size_t max) : maxMemory(max), usedMemory(0) {}
    void* allocate(size_t size) override {
        if (usedMemory + size > maxMemory) {
            // 处理内存不足情况,例如抛出异常
            throw std::bad_alloc();
        }
        usedMemory += size;
        return ::operator new(size);
    }
    void deallocate(void* ptr, size_t size) override {
        usedMemory -= size;
        ::operator delete(ptr);
    }
};

// 3. 共享指针自定义分配器封装
template <typename T, typename Allocator = BaseAllocator>
class CustomSharedPtrAllocator {
private:
    Allocator& allocator;
public:
    CustomSharedPtrAllocator(Allocator& alloc) : allocator(alloc) {}
    T* allocate(size_t n) {
        return static_cast<T*>(allocator.allocate(n * sizeof(T)));
    }
    void deallocate(T* p, size_t n) {
        allocator.deallocate(p, n * sizeof(T));
    }
};

// 4. 使用示例
int main() {
    LimitedMemoryAllocator limitedAllocator(1024);
    CustomSharedPtrAllocator<int, LimitedMemoryAllocator> alloc(limitedAllocator);
    std::shared_ptr<int, CustomSharedPtrAllocator<int, LimitedMemoryAllocator>> ptr(alloc.allocate(1), [&alloc](int* p) { alloc.deallocate(p, 1); });
    return 0;
}