#pragma once #ifndef _M_ALLOCATOR #define _M_ALLOCATOR #include <new> //用于定向开辟内存 #include <cstddef> //用于存储中间量的类型,ptrdiff_t和size_t #include <cstdlib> //exit() #include <climits> //UINT_MAX #include <iostream> //cerr namespace m_allocator { template<class T> inline T* _m_allocate(ptrdiff_t size, T*) //ptrdiff_t, 两个指针距离,个人你认为是long int类型 { set_new_handler(0); //set_new_handler(0)主要是为了卸载目前的内存分配异常处理函数 //这样一旦分配内存失败的话,C++就会强制性抛出std:bad_alloc异常,而不是跑到处理某个异常处理函数去处理 T* temp = (T*)(::operator new((size_t)(size* sizeof(T*)))); if (temp == 0) { cerr << "out of memory" << endl; exit(1); } return temp; } //释放内存 template<class T> inline void _m_deallocate(T* buffer) { ::operator delete (buffer); } //开辟空间,构造对象 template<class T1, class T2> inline void _m_construct(T1* p, const T2& value) { new(p) T1(value); } //析构函数 template<class T> inline void _m_destory(T* ptr) { ptr->~T(); } template<class T> class _m_alloctor { public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& referance; typedef const T& const_referance; typedef size_t size_type; typedef ptrdiff_t difference_type; template<class U> struct m_rebind { typedef _m_alloctor<U> other; }; pointer allocate(size_type n, const void* hint = 0) { return _m_allocate((difference_type)n, (pointer)0); } void deallocate(pointer p, size_type n) { _m_deallocate(p); } void construct(pointer p, const T& value) { _m_construct(p, value); } void destroy(pointer p) { _m_destory(p); } pointer address(referance x) { return pointer(&x); } const_pointer address(const_referance x) { return const_pointer(&x); } size_type max_size() const { return size_type(UINT_MAX / sizeof(T)); } }; } #endif // !_M_ALLOCATOR
#include "m_allocator.h" #include <vector> #include <iostream> using namespace std; int main() { int ia[5] = {0,1,2,3,4}; unsigned int i = 0; vector<int, m_allocator::_m_alloctor<int> > iv(ia,ia + 5); for (auto i = iv.begin(); i != iv.end(); i++) { printf("%d", *i); } printf("%s", " "); return 0; }
将以上空间配置器 m_allocator::_m_alloctor应用于程序中,只能有限度搭配PJ STL 和RW STL(两种不同版本STL源码),因为PJ STL未完全遵循STL规格,其所供应的许多容器都需要一个非标准的空间配置器接口allocator::_Charalloc(), 而RW STL在很多容器身上运用了缓冲区,情况更复杂,m_allocator
::_m_alloctor无法与之兼容,至于完全无法应用于SGI STL, 是因为SGI STL在这个项目上用上了自己所定义的一套标准,并没有太多遵循STL标准规格。
事实上SGI STL仍然提供了一个标准的配置器接口simple_alloc,只是把它做了一层隐藏, 且缺省的空间配置器并不是该接口而已。