gpt4 book ai didi

c++ - 将 std::unique_ptr 与分配器一起使用

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

这次我在尝试分配器,感觉有很多机会泄漏资源。所以我想如果我使用 std::unique_ptr 来处理它们会怎样。我尝试使用 std::vector 的分配器。我的代码是这样的:-

// allocator
#include <iostream>
#include <vector>
#include <memory>
using namespace std;

class X
{
int x,ID;
static int i;
public:
X()
{
cout<<"constructing ";
ID=++i;
cout<<"ID="<<ID<<'\n';
}
X(int a)
{
x=a;
cout<<"constructing ";
ID=++i;
cout<<"ID="<<ID<<'\n';
}
void get()
{
cout<<"enter x: ";
cin>>x;
}
void disp()
{
cout<<"x="<<x<<'\t';
}
~X()
{
cout<<"destroying ID="<<ID<<'\n';
}
};
int X:: i=0;

int main()
{
ios::sync_with_stdio(false);
vector<X> v;
auto alloc = v.get_allocator();
unsigned int i=0;

X *p(alloc.allocate(5));
for (i=0;i<5;++i)
alloc.construct (&p[i], i+1);
unique_ptr<X[]> ptr(p);

cout<<"\nthe elements are:-\n";
for (i=0;i<5;++i)
{
ptr[i].disp();
cout << '\t' << (long long)alloc.address(ptr[i]) << '\n';
}
cout<<"\n";

/*for (i=0;i<5;++i)
alloc.destroy(&p[i]);
deallocate(p,16)*/

return 0;
}

不幸的是,此代码崩溃显示 UB。所以我该怎么做 ?我应该如何操作我的代码以使其适合 std::unique_ptr

最佳答案

template<typename T>
std::unique_ptr<T[], std::function<void(T *)>> make_T(X *ptr, std::allocator<T> alloc, std::size_t size) {
auto deleter = [](T *p, std::allocator<T> alloc, std::size_t size) {
for (int i = 0; i < size; ++i) {
alloc.destroy(&p[i]);
}
alloc.deallocate(p, sizeof(T) * size);
};

return {ptr, std::bind(deleter, std::placeholders::_1, alloc, size)};
}



int main(int argc, const char * argv[]) {
std::allocator<X> alloc = std::allocator<X>();

X *p = alloc.allocate(5);
for (int i = 0; i < 5; ++i) {
alloc.construct(&p[i], i + 1);
}

auto ptr = make_T(p, alloc, 5);

return 0;
}

也可以写一个给你构造对象:

template<typename T, typename... Args>
std::unique_ptr<T[], std::function<void(T *)>> make_T_Construct(std::allocator<T> alloc, std::size_t size, Args... args) {

X *ptr = alloc.allocate(size);

for (std::size_t i = 0; i < size; ++i) {
alloc.construct(&ptr[i], std::forward<Args>(args)...);
}


auto deleter = [](T *p, std::allocator<T> alloc, std::size_t size) {
for (std::size_t i = 0; i < size; ++i) {
alloc.destroy(&p[i]);
}
alloc.deallocate(p, sizeof(T) * size);
};

return {ptr, std::bind(deleter, std::placeholders::_1, alloc, size)};
}

int main(int argc, const char * argv[]) {
std::allocator<X> alloc = std::allocator<X>();

auto ptr = make_T_Construct(alloc, 5, 100);

return 0;
}

编辑:要执行您想要的操作(跟踪分配),您必须使用自定义分配器自行跟踪内存分配。

template<typename T>
struct Allocator
{
typedef T value_type;

Allocator() noexcept {};

template<typename U>
Allocator(const Allocator<U>& other) throw() {};

T* allocate(std::size_t n, const void* hint = 0)
{
T* memory = static_cast<T*>(::operator new(n * (sizeof(T) + sizeof(bool))));

for (std::size_t i = 0; i < n * (sizeof(T) + sizeof(bool)); ++i)
{
*reinterpret_cast<bool*>(reinterpret_cast<char*>(memory) + sizeof(bool)) = false;
}

return memory;
}

void deallocate(T* ptr, std::size_t n)
{
::operator delete(ptr);
}

void construct(T* p, const T& arg)
{
destroy(p);
new(p) T(arg);
*reinterpret_cast<bool*>(reinterpret_cast<char*>(p) + sizeof(bool)) = true;
}

template<class U, class... Args>
void construct(U* p, Args&&... args)
{
destroy(p);
::new(p) U(std::forward<Args>(args)...);

*reinterpret_cast<bool*>(reinterpret_cast<char*>(p) + sizeof(bool)) = true;
}

void destroy(T* p)
{
if (*reinterpret_cast<bool*>(reinterpret_cast<char*>(p) + sizeof(bool))) {
p->~T();
*reinterpret_cast<bool*>(reinterpret_cast<char*>(p) + sizeof(bool)) = false;
}
}

template<class U>
void destroy(U* p)
{
if (*reinterpret_cast<bool*>(reinterpret_cast<char*>(p) + sizeof(bool))) {
p->~U();
*reinterpret_cast<bool*>(reinterpret_cast<char*>(p) + sizeof(bool)) = false;
}
}
};

template <typename T, typename U>
inline bool operator == (const Allocator<T>&, const Allocator<U>&)
{
return true;
}

template <typename T, typename U>
inline bool operator != (const Allocator<T>& a, const Allocator<U>& b)
{
return !(a == b);
}

关于c++ - 将 std::unique_ptr 与分配器一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33845132/

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