gpt4 book ai didi

c++ - 替换全局操作符new/delete并在其中分配内存,导致堆损坏

转载 作者:行者123 更新时间:2023-12-03 07:15:29 25 4
gpt4 key购买 nike

#include <cstdlib>
#include <memory>
#include <unordered_map>

template <class T>
struct allocator {
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;

allocator() = default;

template <class U>
allocator(const allocator<U>&) {}

T* allocate(std::size_t n) const { return (T*)malloc(n); } // debugger breaks here
void deallocate(T* p, std::size_t) const { free(p); }
};

using allocations_map =
std::unordered_map<void*, std::size_t, std::hash<void*>,
std::equal_to<void*>,
allocator<std::pair<void* const, std::size_t>>>;

allocations_map allocations; // heap corruption in the constructor

void* operator new(std::size_t n) {
auto p = malloc(n);
allocations.emplace(p, n);
return p;
}

void operator delete(void* p) noexcept {
allocations.erase(p);
free(p);
}

int main() { std::vector<int> v(5); }
为什么我破坏了aslocations_map的构造函数中的堆?调试器在构造函数内部的自定义分配器的malloc调用中检测到第一个堆损坏。
有没有比编写一个非日志记录的自定义分配器分配分配映射更好的解决方案?容器显然不应记录自己的分配。
如注释中所述,我还尝试了两种单例方法,但均未成功:
allocations_map& get_allocations_map()
{
static allocations_map* allocations_ptr = nullptr;
if (allocations_ptr == nullptr)
{
allocations_ptr = (allocations_map*) malloc(sizeof(allocations_map));
allocations_ptr = new(allocations_ptr)allocations_map;
}
return *allocations_ptr;
}


allocations_map& get_allocations_map()
{
static allocations_map allocations;
return allocations;
}

最佳答案

std::allocator::allocate分配器分配n“事物”而不是n字节。您应该更改:

T* allocate(std::size_t n) const { return (T*)malloc(n); }
至:
T* allocate(std::size_t n) const { return (T*)malloc(sizeof(T) * n); }

Why do i corrupt the heap in the constructor of allocations_map?


因为存储在该映射中的元素的构造函数访问分配的内存超出范围。

关于c++ - 替换全局操作符new/delete并在其中分配内存,导致堆损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64592353/

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