3 分配器allocator和new重载
3.3 分配器allocator详解
分配器allocator实现容器算法时不同于new,它可以将对象内存分配和构造分离。 allocator的使用如下所示:
# include <iostream>
using namespace std;
class XData {
public:
XData()
{
cout << "construct function XData()" << endl;
}
~XData()
{
cout << "destory function ~XData()" << endl;
}
};
int main()
{
allocator<XData> xdata_alloc;
int size = 2;
auto dataArr = xdata_alloc.allocate(size);
for (size_t i = 0; i < size; i++)
{
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;
}
3.4 自定义allocator
可以实现内存共享、内存泄漏探测,预分配对象存储和内存池 演示自定义vector和list分配器
#include <iostream>
#include <vector>
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()
3.5 未初始化内存复制分析
#include <iostream>
#include <vector>
#include <string.h>
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 <iostream>
#include <vector>
#include <string.h>
#include <memory>
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()
{
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;
}
|