gpt4 book ai didi

c++ - 模板类的自动内存池功能

转载 作者:行者123 更新时间:2023-11-30 03:35:09 31 4
gpt4 key购买 nike

story 的延续.

考虑安全软件,其中不允许使用碎片进行动态分配。仅当类显式定义运算符 new 时才允许动态分配和 delete以避免碎片化。

现在我们有机会优化运算符 new 的显式定义和 delete对于我们想要上的任何类(class)。乍一看,任何类都可以继承的模板类是最终用户最简单明了的使用方式。

template<class T, unsigned size>
class MemoryPool
{
private:
struct Pool
{
bool allocated __attribute__ ((aligned (sizeof(void*))));
uint8_t memory[sizeof(T)] __attribute__ ((aligned (sizeof(void*))));
};
static std::array<uint8_t[sizeof(Pool)], size> memoryPool;

public:
void* operator new(std::size_t) noexcept
{
T* ret = nullptr;
for(auto it = memoryPool.begin(); it != memoryPool.end(); ++it)
{
/* ... */
}
return ret;
}

void operator delete(void* ptr) noexcept
{
for(auto it = memoryPool.begin(); it != memoryPool.end(); ++it)
{
/* ... */
}
}
};

如果这是童话故事,用 MemoryPool 声明类会很甜蜜。

class Interface
{/*...*/};

class Foo : public Interface, MemoryPool<Foo, 8>
{/*...*/};

class Bar : public Interface
{/*...*/};

和对象的声明:

Foo* foo = new Foo(); // goes to dedicated memory pool
Bar* bar = new Bar(); // fails on build

但即使 static std::array<uint8_t[sizeof(Pool)], size> memoryPool;是静态的并且会超出类,所以它不会改变类的大小,编译器会提示 Foo不完整,无法推断出 Foo 的大小

src/metal/dynamic.hpp:14:24: error: invalid application of 'sizeof' to incomplete type 'Foo'
uint8_t memory[sizeof(T)] __attribute__ ((aligned (sizeof(void*))));

是否可以解决此“不完整类型”错误?

或者我应该完全重新设计解决方案吗?

最佳答案

问题是 MemoryPool 实例化时 Foo 还不是一个完整的类型。

clang's error message非常具体:

main.cpp:10:24: error: invalid application of 'sizeof' to an incomplete type 'Foo'
uint8_t memory[sizeof(T)] __attribute__ ((aligned (sizeof(void*))));
^~~~~~~~~
main.cpp:13:31: note: in instantiation of member class 'MemoryPool<Foo, 8>::Pool' requested here

static std::array<uint8_t[sizeof(Pool)], size> memoryPool;
^
main.cpp:35:20: note: in instantiation of template class 'MemoryPool<Foo, 8>' requested here
class Foo : public MemoryPool<Foo, 8>
^
main.cpp:35:7: note: definition of 'Foo' is not complete until the closing '}'
class Foo : public MemoryPool<Foo, 8>
^

您可以通过延迟应用程序 sizeof 直到 Foo 是一个完整类型来解决这个问题。

这可以通过静态成员函数访问memoryPool来完成:

template<class T, unsigned size>
class MemoryPool
{
private:
struct Pool
{
bool allocated __attribute__ ((aligned (sizeof(void*))));
uint8_t memory[sizeof(T)] __attribute__ ((aligned (sizeof(void*))));
};

template <typename P>
static std::array<uint8_t[sizeof(P)], size>& getPool()
{
static std::array<uint8_t[sizeof(P)], size> memoryPool;
return memoryPool;
}
public:
void* operator new(std::size_t) noexcept
{
T* ret = nullptr;
for(auto it = getPool<Pool>().begin(); it != getPool<Pool>().end(); ++it)
{
/* ... */
}
return ret;
}
};

live example

C++14 允许稍微简单的实现:

template<class T, unsigned size>
class MemoryPool
{
private:
struct Pool
{
bool allocated __attribute__ ((aligned (sizeof(void*))));
uint8_t memory[sizeof(T)] __attribute__ ((aligned (sizeof(void*))));
};

static auto& getPool()
{
static std::array<uint8_t[sizeof(Pool)], size> memoryPool;
return memoryPool;
}
public:
void* operator new(std::size_t) noexcept
{
T* ret = nullptr;
for(auto it = getPool().begin(); it != getPool().end(); ++it)
{
/* ... */
}
return ret;
}
};

live example

关于c++ - 模板类的自动内存池功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41462395/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com