gpt4 book ai didi

c++ - 尝试创建池分配器时 VC12 中出现奇怪的错误消息

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:43:54 25 4
gpt4 key购买 nike

我正在尝试创建一个简单的池分配器,它可以与 list 和 map 等容器一起使用。首先,我上课 free_list它继承自容器使用的节点类型,并使用专门的前向链表(其所有内存都已分配——分配发生在分配器分配第一个项目时)来提供和收回分配器请求的内存allocatedeallocate功能。然后我上课pool_alloc它实现分配器本身并在其分配和释放函数中返回和接受 free_list<T>对象类型。

问题 child 是这个陈述:m_next->give_back(ptr);pool_alloc::deallocate 下,它返回 VC12 错误 C2664:它说我无法从类型“free_list<T>* 转换” ' 键入 ' free_list<free_list<T>>* '.

我不明白为什么free_list<T>::give_back期望类型 free_list<free_list<T>>*当人们期望它期待free_list<T>* .

有什么办法可以解决这个问题吗?

完整的源代码如下:

#include <algorithm>

template<class T>
class free_list : public T {
public:
free_list* init(std::size_t num_elements) {

m_next = this;
free_list* temp = m_next + 1;

free_list* runner = m_next;
for (std::size_t s = 1; s < num_elements; ++s) {
runner->m_next = temp;
runner = temp;
temp = runner + 1;
}
runner->m_next = nullptr;

return m_next;
}

free_list* obtain() {
free_list* head = m_next;
m_next = m_next->m_next;
return head;
}

void give_back(free_list* ptr) {
ptr->m_next = m_next;
m_next = ptr;
}

free_list* m_next;

};

template<class T>
class pool_alloc {
typedef pool_alloc<T> myt;

public:
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef free_list<T> value_type;
typedef T& reference;
typedef const T& const_reference;
typedef free_list<T>* pointer;
typedef const free_list<T>* const_pointer;

template<class U>
struct rebind {
typedef pool_alloc<U> other;
};

pool_alloc() : data(nullptr), m_next(nullptr), capacity(4096), allocated(0) {}
pool_alloc(std::size_t capacity) : data(nullptr), m_next(nullptr), capacity(capacity), allocated(0) {}

T* address(reference ref) {
return &ref;
}

const T* address(const_reference ref) const {
return &ref;
}

std::size_t max_size() const {
return capacity;
}

pointer allocate(std::size_t) {
if (allocated >= capacity) throw(std::bad_alloc());
if (allocated == 0) {
data = (void*) new char[capacity * sizeof(free_list<T>)];
m_next = static_cast<free_list<value_type>*>(data);
m_next->init(capacity);
}
return m_next->obtain();
}

void deallocate(pointer ptr, std::size_t) {
m_next->give_back(ptr);
--allocated;
if (allocated == 0) {
delete[](char*)(data);
data = nullptr;
m_next = nullptr;
}
}

template<class T, class... Args>
void construct(T* ptr, Args&&... args) {
::new ((void*) ptr) T(std::forward<Args>(args)...);
}

template <class T>
void destroy(T* ptr) {
ptr->~T();
}

bool operator==(const myt& other) {
return (char)(data) == (char)(other.data);
}

bool operator!=(const myt& other) {
return !operator==(other);
}

private:

void* data;
free_list<value_type>* m_next;
std::size_t capacity;
std::size_t allocated;

};

最佳答案

没那么奇怪:你定义了value_type (错误地)是 free_list<T>而不是 T , 所以 m_next类型为 free_list<free_list<T>> . pointerconst_pointer有同样的问题。

其他问题:

  • pool_alloc没有定义正确的复制/移动/赋值运算符。
  • pool_alloc没有接受 const pool_alloc<U>& 的模板化构造函数, 所以你将无法初始化
  • pool_alloc::allocate如果有人试图制作 std::vector<T, pool_alloc<T>> 将会做出可怕的事情.您可能应该断言参数为 1 或回退到 ::operator new(n * sizeof(T))如果参数大于 1。
  • operator==operator!=应该是 const .
  • constructdestroy也可以是 const ,甚至 static .
  • 没有必要同时保留 datam_next , 因为它们是相同值的不同类型别名 - 只需转换 m_nextvoid*随时随地data .
  • 正在转储 deallocate 中的内存块而不是 ~pool_alloc可能具有病理表现,例如 std::stack<T, std::list<T, pool_alloc<T>> .
  • free_list<T>::init 中的“列表”初始化指向每个节点的 m_next指向自身的指针而不是构建列表。应该是:

    void init(std::size_t num_elements) {
    for (std::size_t i = 0; i < num_elements - 1; ++i) {
    this[i]->m_next = &this[i + 1];
    }
    this[num_elements - 1]->m_next = nullptr;
    }

关于c++ - 尝试创建池分配器时 VC12 中出现奇怪的错误消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24367763/

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