-
-
Save seaside2mm/8f63e26ef036551c3c064d17ebd65107 to your computer and use it in GitHub Desktop.
#include <cstdlib> | |
#include <new> | |
#include <limits> | |
#include <iostream> | |
#include <vector> | |
template <class T> | |
struct Mallocator | |
{ | |
typedef T value_type; | |
Mallocator () = default; | |
template <class U> constexpr Mallocator (const Mallocator <U>&) noexcept {} | |
[[nodiscard]] T* allocate(std::size_t n) { | |
if (n > std::numeric_limits<std::size_t>::max() / sizeof(T)) | |
throw std::bad_array_new_length(); | |
if (auto p = static_cast<T*>(std::malloc(n*sizeof(T)))) { | |
report(p, n); | |
return p; | |
} | |
throw std::bad_alloc(); | |
} | |
void deallocate(T* p, std::size_t n) noexcept { | |
report(p, n, 0); | |
std::free(p); | |
} | |
private: | |
void report(T* p, std::size_t n, bool alloc = true) const { | |
std::cout << (alloc ? "Alloc: " : "Dealloc: ") << sizeof(T)*n | |
<< " bytes at " << std::hex << std::showbase | |
<< reinterpret_cast<void*>(p) << std::dec << '\n'; | |
} | |
}; | |
template <class T, class U> | |
bool operator==(const Mallocator <T>&, const Mallocator <U>&) { return true; } | |
template <class T, class U> | |
bool operator!=(const Mallocator <T>&, const Mallocator <U>&) { return false; } | |
int main() | |
{ | |
std::vector<int, Mallocator<int>> v(8); | |
v.push_back(42); | |
} |
#include <list> | |
#include <memory> | |
#include <chrono> | |
#include <iostream> | |
#ifdef __GNUC__ | |
#include <ext/array_allocator.h> | |
#include <ext/mt_allocator.h> | |
#include <ext/debug_allocator.h> | |
#include <ext/pool_allocator.h> | |
#include <ext/bitmap_allocator.h> | |
#include <ext/malloc_allocator.h> | |
#include <ext/new_allocator.h> | |
#endif | |
using namespace std; | |
int main() { | |
#ifdef __GNUC__ | |
list <string, allocator<string>> c1; | |
list <string, __gnu_cxx::malloc_allocator<string>> c2; | |
list <string, __gnu_cxx::new_allocator<string>> c3; | |
list <string, __gnu_cxx::__pool_alloc<string>> c4; | |
list <string, __gnu_cxx::__mt_alloc<string>> c5; | |
list <string, __gnu_cxx::bitmap_allocator<string>> c6; | |
auto start = chrono::steady_clock::now(); | |
char buf[10]; | |
for (long i = 0; i < 10000; ++i) { | |
snprintf(buf, 10, "%d", i); | |
c2.push_back(string(buf)); | |
} | |
auto end = chrono::steady_clock::now(); | |
auto time = chrono::duration_cast<chrono::microseconds>(end - start).count(); | |
std::cout << time; | |
#endif | |
} |
一组typedef: -allocator::value_type -allocator::pointer -allocator::const_pointer -allocator::reference -allocator::const_reference -allocator::size_type -allocator::difference_type
allocator::rebind allocator的内嵌模板,需要定义other成员 allocator::allocator() 构造函数 allocator::allocator(const allocator&) 拷贝构造函数 allocator::~allocator() 析构函数 pointer allocator::address(reference x)const 返回对象地址 pointer allocator::allocate(size_type n, const void *=0) 分配空间 void allocator::deallocator(pointer p, size_type n) 释放空间 size_type allocator::max_size() const 可以分配的最大空间 void allocator::construct(pointer p, const T&x) 构造分配内存中的对象 void allocator::destroy(pointer p) 析构内存对象
也就是new_allocator,对new/delete函数进行封装 源码剖析,推荐
bitmap_allocator 使用位来表示内存是否使用的分配器 debug_allocator 加入调试信息的分配器 malloc_allocator 简单地封装了malloc和free函数 pool_allcator 基于内存池的实现 throw_allocator 用于异常 mt_allocator 对多线程环境进行了优化
上述分配器的实现都在GNU的ext目录下,使用范例如下:
#include <ext/bitmap_allocator.h>
vector<int, __gnu_cxx::bitmap_allocator<int>> vec;