分配器allocator实现容器算法时不同于new,它可以将对象内存分配和构造分离。
allocator的使用如下所示:
# include
using namespace std;
class XData {
public:
XData()
{
cout << "construct function XData()" << endl;
}
~XData()
{
cout << "destory function ~XData()" << endl;
}
};
int main()
{
/**
* @brief
* #include
* std::allocator
* address:C++17 弃用, C++20中移除
* max_size:C++17 弃用, C++20中移除
* construct:C++17 弃用, C++20中移除
* destory:C++17 弃用, C++20中移除
* allocator:分配未初始化的存储
* deallocator:解分配存储
*/
allocator<XData> xdata_alloc;
int size = 2;
// 分配内存空间,不分配内存
auto dataArr = xdata_alloc.allocate(size);
for (size_t i = 0; i < size; i++)
{
// allocator_traits 类模板提供访问分配器(Allocator)的各种属性的标准化方式。
// 调用构造函数
allocator_traits<decltype(xdata_alloc)>::construct(xdata_alloc, &dataArr[i]);
// 调用析构函数
allocator_traits<decltype(xdata_alloc)>::destroy(xdata_alloc, &dataArr[i]);
}
// 清理空间,不调用析构
xdata_alloc.deallocate(dataArr, size);
return 0;
}
可以实现内存共享、内存泄漏探测,预分配对象存储和内存池
演示自定义vector和list分配器
#include
#include
using namespace std;
class XData {
public:
XData()
{
cout << "construct function XData(), index = " << index << endl;
}
XData(const XData &b)
{
this->index = b.index;
cout << "copy function XData(), index = " << index << endl;
}
~XData()
{
cout << "destory function ~XData()" << endl;
}
int index = 0;
};
template<typename Ty>
class MyAllocator {
public:
using value_type = Ty;
MyAllocator()=default;
template<class other>
MyAllocator(const MyAllocator<other> &) {};
void deallocate(Ty *const ptr, const size_t count)
{
free(ptr);
}
Ty *allocate(size_t count)
{
cout << "allocate " << count << endl;
return static_cast<Ty*>(malloc(sizeof(Ty) * count));
}
};
int main()
{
vector<XData, MyAllocator<XData>> vec;
XData d;
d.index = 1;
vec.push_back(d);
d.index = 2;
vec.push_back(d);
d.index = 3;
vec.push_back(d);
return 0;
}
输出结果:
construct function XData(), index = 0
allocate 1
copy function XData(), index = 1
allocate 2
copy function XData(), index = 2
copy function XData(), index = 1
destory function ~XData()
allocate 4
copy function XData(), index = 3
copy function XData(), index = 1
copy function XData(), index = 2
destory function ~XData()
destory function ~XData()
destory function ~XData()
destory function ~XData()
destory function ~XData()
destory function ~XData()
#include
#include
#include
using namespace std;
class XData {
public:
XData()
{
cout << "construct function XData(), index = " << index << endl;
}
XData(const XData &b)
{
this->index = b.index;
cout << "copy function XData(), index = " << index << endl;
}
XData& operator=(const XData &d)
{
this->index = d.index;
cout << "operator= function XData(), index = " << index << endl;
return *this;
}
~XData()
{
cout << "destory function ~XData()" << endl;
}
int index = 0;
};
template<typename Ty>
class MyAllocator {
public:
using value_type = Ty;
MyAllocator()=default;
template<class other>
MyAllocator(const MyAllocator<other> &) {};
void deallocate(Ty *const ptr, const size_t count)
{
free(ptr);
}
Ty *allocate(size_t count)
{
cout << "allocate " << count << endl;
return static_cast<Ty*>(malloc(sizeof(Ty) * count));
}
};
int main()
{
unsigned char buf[1024] = {0};
XData datas[3];
cout << "===============memcpy==================" << endl;
memcpy(buf, &datas, sizeof(datas));
cout << "===============std::copy==================" << endl;
// 将对象进行赋值操作,对象没有做初始化
copy(begin(datas), end(datas), reinterpret_cast<XData*>(buf));
cout << "===============uninitialized_copy==================" << endl;
// 将对象进行拷贝构造操作,对象做了初始化
uninitialized_copy(begin(datas), end(datas), reinterpret_cast<XData*>(buf));
return 0;
}
输出结果:
construct function XData(), index = 0
construct function XData(), index = 0
construct function XData(), index = 0
===============memcpy==================
===============std::copy==================
operator= function XData(), index = 0
operator= function XData(), index = 0
operator= function XData(), index = 0
===============uninitialized_copy==================
copy function XData(), index = 0
copy function XData(), index = 0
copy function XData(), index = 0
destory function ~XData()
destory function ~XData()
destory function ~XData()
#include
#include
#include
#include
using namespace std;
class XData {
public:
XData()
{
cout << "construct function XData(), index = " << index << endl;
}
XData(const XData &b)
{
this->index = b.index;
cout << "copy function XData(), index = " << index << endl;
}
XData& operator=(const XData &d)
{
this->index = d.index;
cout << "operator= function XData(), index = " << index << endl;
return *this;
}
~XData()
{
cout << "destory function ~XData()" << endl;
}
int index = 0;
};
template<typename Ty>
class MyAllocator {
public:
using value_type = Ty;
MyAllocator()=default;
template<class other>
MyAllocator(const MyAllocator<other> &) {};
void deallocate(Ty *const ptr, const size_t count)
{
free(ptr);
}
Ty *allocate(size_t count)
{
cout << "allocate " << count << endl;
return static_cast<Ty*>(malloc(sizeof(Ty) * count));
}
};
int main()
{
// C++ 17 20
// construct_at destory对象构造和销毁
// C++17 destory对象的销毁
// C++20 construct_at对象构造
int size = 3;
// 分配内存
auto data = static_cast<XData*>(malloc(sizeof(XData) * size));
for (size_t i = 0; i < size; i++)
{
if (data) {
std::construct_at(&data[i]); // 调用构造函数,构造对象
}
}
// 调用析构函数
destory(data, data + size);
free(data);
return 0;
}