在VC12中尝试创建池分配器时出现奇怪的错误消息
Bizarre error message in VC12 when attempting to create pool allocator
我正在尝试创建一个简单的池分配器,可以与列表和映射等容器一起工作。首先,我有一个类free_list
,它继承了容器使用的节点类型,并使用一个专门的前向链表(它的所有内存都已经分配——分配发生在分配器分配第一个项目时)来给出和收回分配器的allocate
和deallocate
函数中请求的内存。然后我有pool_alloc
类,它实现了分配器本身,并在其分配和释放函数中返回和接受free_list<T>
对象类型。
问题子是这个语句:pool_alloc::deallocate
下的m_next->give_back(ptr);
,它返回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>>
类型。pointer
和const_pointer
也有同样的问题。
-
pool_alloc
没有定义正确的复制/移动/赋值操作符 -
pool_alloc
没有接受const pool_alloc<U>&
的模板化构造函数,所以你将无法初始化 如果有人试图制作 -
operator==
和operator!=
应该是const
-
construct
和destroy
也可以是const
,甚至static
。 - 没有必要同时保留
data
和m_next
,因为它们是相同值的不同类型别名-只要在需要data
时将m_next
转换为void*
即可。 - 将内存块转储到
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; }
std::vector<T, pool_alloc<T>>
, pool_alloc::allocate
会做出可怕的事情。您可能应该断言参数为1,或者在参数大于1时退回到::operator new(n * sizeof(T))
。相关文章:
- boost::进程间消息队列引发错误
- C++错误消息*成员参考.**初学者*
- 如何通过参数抛出错误消息
- glad 导致 glfwSwapBuffers 返回错误消息
- FindPackageHandleStandardArgs.cmake:137 的 CMake 错误(消息):找不到 Boost (缺少:正则表达式)(找到合适的版本"1.72.0",
- 如何接受 [ENTER] 键作为无效输入并发送错误消息
- 重新定义预定义的 errno 错误消息 (E2BIG)
- SDL 映像:无法打开映像,仅显示错误消息
- 错误消息:使用"string* +="后"no match for 'operator+='"
- 使用公钥加密消息:BER 解码错误
- 我在主函数的左括号上不断收到错误,消息为obj\Debug\main.o||在函数"ZN11linked_listC1Ev"中:|
- 错误消息"expected expression"....有人知道它为什么这么说吗?
- 在 Eclipse: "error: no match for 'operator='" 中获取错误消息
- 出现分段错误时,更改显示的消息错误
- 使用C 中的OPENSL RSA函数解密消息错误
- Linux汇编程序消息错误c++
- C++写入消息错误
- 发送http post消息错误报告的安全方式
- C++,在尝试创建类时收到此消息:错误:没有在类“media”中声明的“void media::*()”成员函数
- 编译器错误消息错误:令牌之前的预期')' '*'。我的构造函数出错