C++ 2003也可以,allocator类写起来并不难,下面是我在vs2005中使用的小例子,在clang下编译采用。它计算某些使用 unordered_map 请求的内存字节数。
ps。您说您有一块内存,您希望自定义分配器从中进行分配,要使其正常工作,您将需要某种分配器来处理频繁的分配/解除分配-为此,您可能需要查看@ 987654321@可以配置使用这样的内存块。
http://coliru.stacked-crooked.com/a/e27368e784123954
#include <iostream>
#include <string>
#include <memory>
#include <unordered_map>
#include <limits>
int total_alloc = 0;
template <class T>
class MyAllocator {
public:
// type definitions
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
// rebind allocator to type U
template <class U>
struct rebind {
typedef MyAllocator<U> other;
};
// return address of values
pointer address(reference value) const {
return &value;
}
const_pointer address(const_reference value) const {
return &value;
}
/* constructors and destructor
* - nothing to do because the allocator has no state
*/
MyAllocator() throw() {
}
MyAllocator(const MyAllocator&) throw() {
}
template <class U>
MyAllocator(const MyAllocator<U>&) throw() {
}
~MyAllocator() throw() {
}
// return maximum number of elements that can be allocated
size_type max_size() const throw() {
return (std::numeric_limits<size_t>::max)() / sizeof(T);
}
// allocate but don't initialize num elements of type T
pointer allocate(size_type num, const void* = 0) {
pointer ret = (pointer)malloc(num*sizeof(T));
total_alloc += num*sizeof(T);
return ret;
}
// initialize elements of allocated storage p with value value
void construct(pointer p, const T& value) {
::new((void*)p) T(value);
}
// destroy elements of initialized storage p
void destroy(pointer p) {
// destroy objects by calling their destructor
p->~T();
}
// deallocate storage p of deleted elements
void deallocate(pointer p, size_type num) {
total_alloc -= num*sizeof(T);
free(p);
}
};
/// return that all specializations of this allocator are interchangeable
template <class T1, class T2>
bool operator== (const MyAllocator<T1>&,
const MyAllocator<T2>&) throw() {
return true;
}
template <class T1, class T2>
bool operator!= (const MyAllocator<T1>&,
const MyAllocator<T2>&) throw() {
return false;
}
typedef std::basic_string<char, std::char_traits<char>, MyAllocator<char> > stringx;
namespace std
{
template<>
struct hash<stringx> {
size_t operator()(const stringx &str) const {
std::hash<const char*> str_hash;
return str_hash(str.c_str());
}
};
}
typedef std::unordered_map<stringx, int,
std::hash<stringx>,
std::equal_to<stringx>,
MyAllocator<std::pair<const stringx, std::pair<stringx, int> > > > sample_map_type;
int main()
{
sample_map_type sample_map;
sample_map["test1"] = 1;
sample_map["test2"] = 2;
for (auto elem : sample_map) {
std::cout << elem.first << " -> " << elem.second << std::endl;
}
std::cout << "total_alloc = " << total_alloc << std::endl;
}