gpt4 book ai didi

c++ - 错误的分配器实现

转载 作者:行者123 更新时间:2023-11-30 04:33:14 25 4
gpt4 key购买 nike

我有一个非常简单的问题。我一直在搞一个非线程安全的分配器。分配器是一个相当简单的内存竞技场策略 - 分配一个大块,将所有分配放入其中,不执行任何释放操作,在竞技场破坏时删除所有内存。但是,实际尝试使用此方案会引发访问冲突。

static const int MaxMemorySize = 80000;
template <typename T>
class LocalAllocator
{
public:
std::vector<char>* memory;
int* CurrentUsed;
typedef T value_type;
typedef value_type * pointer;
typedef const value_type * const_pointer;
typedef value_type & reference;
typedef const value_type & const_reference;
typedef std::size_t size_type;
typedef std::size_t difference_type;

template <typename U> struct rebind { typedef LocalAllocator<U> other; };

template <typename U>
LocalAllocator(const LocalAllocator<U>& other) {
CurrentUsed = other.CurrentUsed;
memory = other.memory;
}
LocalAllocator(std::vector<char>* ptr, int* used) {
CurrentUsed = used;
memory = ptr;
}
template<typename U> LocalAllocator(LocalAllocator<U>&& other) {
CurrentUsed = other.CurrentUsed;
memory = other.memory;
}
pointer address(reference r) { return &r; }
const_pointer address(const_reference s) { return &r; }
size_type max_size() const { return MaxMemorySize; }
void construct(pointer ptr, value_type&& t) { new (ptr) T(std::move(t)); }
void construct(pointer ptr, const value_type & t) { new (ptr) T(t); }
void destroy(pointer ptr) { static_cast<T*>(ptr)->~T(); }

bool operator==(const LocalAllocator& other) const { return Memory == other.Memory; }
bool operator!=(const LocalAllocator&) const { return false; }

pointer allocate(size_type n) {
if (*CurrentUsed + (n * sizeof(T)) > MaxMemorySize)
throw std::bad_alloc();
auto val = &(*memory)[*CurrentUsed];
*CurrentUsed += (n * sizeof(T));
return reinterpret_cast<pointer>(val);
}
pointer allocate(size_type n, pointer) {
return allocate(n);
}
void deallocate(pointer ptr, size_type n) {}

pointer allocate() {
return allocate(sizeof(T));
}
void deallocate(pointer ptr) {}
};

我已将 memory 初始化为指向一个大小调整为 MaxMemorySize 的 vector ,并且我还已将 CurrentUsed 初始化为指向一个为零的 int。我将具有这些值的分配器提供给 std::unordered_map 的构造函数,但它一直在 STL 内部引发访问冲突。有什么建议吗?

编辑:这是我的用法:

std::vector<char> memory;
int CurrentUsed = 0;
memory.resize(80000);
std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, LocalAllocator<std::pair<const int, int>>> dict(
std::unordered_map<int, int>().bucket_count(),
std::hash<int>(),
std::equal_to<int>(),
LocalAllocator<std::pair<const int, int>>(&memory, &CurrentUsed)
);
// start timer
QueryPerformanceCounter(&t1);

for (int i=0;i<10000;i++)
dict[i]=i; // crash

编辑:该死的 hell 。当我将大小增加到 1MB 时它起作用了。我必须将它增加到超过 800,000 字节才能让它在不抛出错误的情况下工作。

最佳答案

当我测试这段代码时,rebind 被用于针对同一个内存块请求多个分配器。我把

cout << n << " " << sizeof(T) << " " << typeid(T).name() << endl;

在 allocate(size_type) 的顶部,当我将三个元素添加到 unordered_map 时得到:

1 64 struct std::_List_nod<...>
16 4 struct std::_List_iterator<...>
1 64 struct std::_List_nod<...>
1 64 struct std::_List_nod<...>
1 64 struct std::_List_nod<...>

如果您的实现并非巧合地使用良好的圆形 64 字节请求,则此类将返回未对齐的分配。

关于c++ - 错误的分配器实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7018460/

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