歡迎您光臨本站 註冊首頁

類STL的內存分配,釋放介面

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  DarkSpy 於 2002/7/30 @ ConeosBraintel Software
近幾日一直在開發偶的 EasyCode Windows 版(EasyCode Pro),不過,對於內存管理,自己寫了一套,不用藉助任何的 include 文件。
由於時間關係,沒有寫自己的 set_handler 代碼,不過有時間會加上去的 :)
該代碼您可以任意使用,但是如果出現意外,如硬碟燒毀,無故斷電,光碟機飛盤等等現象,DarkSpy一律不負任何責任 :-)
有一部分代碼沒有很完善,不過90%可以正常使用。
代碼全部遵循是ISO C++98標準,如果您的編譯器無法通過,則是編譯器不支持,而不是代碼問題。
如果您修改了它,請給我一份拷貝,謝謝!

#ifdef __GNUC__
typedef long unsigned int size_t;
#else
#define size_t unsigned int
#endif
namespace __easycode_pro
{
template <typename T>
struct _type_traits
{
typedef T _type;
~_type_traits() { _type().~_type(); }
};
template <typename T>
struct _type_traits<T *>
{
typedef _type_traits<T *> _type;
~_type_traits() { _type().~_type(); }
};
template <typename T>
struct _type_traits<const T>
{
typedef _type_traits<T> _type;
~_type_traits() { _type().~_type(); }
};
template <typename T>
struct _type_traits<const T *>
{
typedef _type_traits<T *> _type;
~_type_traits() { _type().~_type(); }
};
template <>
struct _type_traits<int>
{
~_type_traits() { }
};
template <>
struct _type_traits<unsigned int>
{
~_type_traits() { }
};
template <>
struct _type_traits<int *>
{
~_type_traits() { }
};
template <>
struct _type_traits<unsigned int *>
{
~_type_traits() { }
};
template <>
struct _type_traits<char>
{
~_type_traits() { }
};
template <>
struct _type_traits<unsigned char>
{
~_type_traits() { }
};
template <>
struct _type_traits<char *>
{
~_type_traits() { }
};
template <>
struct _type_traits<unsigned char *>
{
~_type_traits() { }
};
template <>
struct _type_traits<long>
{
~_type_traits() { }
};
template <>
struct _type_traits<unsigned long>
{
~_type_traits() { }
};
template <>
struct _type_traits<long *>
{
~_type_traits() { }
};
template <>
struct _type_traits<unsigned long *>
{
~_type_traits() { }
};
template <>
struct _type_traits<short>
{
~_type_traits() { }
};
template <>
struct _type_traits<unsigned short>
{
~_type_traits() { }
};
template <>
struct _type_traits<short *>
{
~_type_traits() { }
};
template <>
struct _type_traits<bool>
{
~_type_traits() { }
};
template <>
struct _type_traits<float>
{
~_type_traits() { }
};
template <>
struct _type_traits<float *>
{
~_type_traits() { }
};
template <>
struct _type_traits<double>
{
~_type_traits() { }
};
template <>
struct _type_traits<double *>
{
~_type_traits() { }
};
};

namespace __easycode_pro
{
template <typename T>
class allocator
{
protected:
void * operator new (size_t size)
{ return ::operator new (size); }
void operator delete(void * p)
{ ::operator delete (p); }

void * operator new[](size_t size, int i)
{ return ::operator new (size * i + 1); }
void operator delete[](void *p, int i)
{ ::operator delete (p); }

void * operator new(size_t size, void *p)
{ return p; }
void operator delete(void *p, void *p2)
{ ::operator delete(p); }
public:
typedef T t_type;
typedef t_type* t_pointer;
typedef t_type& t_reference;
typedef int t_value;
public:
allocator(t_pointer pt = 0) { }
~allocator() { }

static t_pointer allocate(allocator<T> p, int how_many) throw(bool);
static void deallocate(t_pointer p) throw(bool);

template <typename U>
static t_pointer placement_allocate(U *p) throw(bool);
template <typename U>
static void placement_deallocate(U *p) throw(bool);
t_pointer operator()(t_pointer t) { return t; }
};

template <typename T, typename Alloc = allocator<T> >
struct mem_alloc
{
static typename Alloc::t_pointer alloc(int how_many)
{ return Alloc::allocate(Alloc(), how_many); }
static void dealloc(T *p)
{ Alloc::deallocate(p); }
template <typename U>
static typename Alloc::t_pointer p_alloc(U *p)
{ return Alloc::template placement_allocate<T>(p); }
template <typename U>
static void p_dealloc(U *p)
{ Alloc::template placement_deallocate<T>(p); }
};

template <typename T>
struct __convert
{
T *data;
__convert() : data(0) {}
operator T(){ return *data; }
operator void *(){}
void * got(T &p) { return &p; }
};
};

#define set_alloc_name(_alloc_type) \
typedef __easycode_pro::mem_alloc<_alloc_type> _alloc_type##_allocator

#define get_address(__type, __value) \
__easycode_pro::__convert<__type>().got(__value)

template <typename T> inline
typename __easycode_pro::allocator<T>::t_pointer
__easycode_pro::allocator<T>::allocate(__easycode_pro::allocator<T> p, int how_many)
throw(bool)
{
t_pointer tmp;
if(how_many<=0) //allocator one of sizeof type memory
tmp = (t_pointer)(allocator<T>::operator new(sizeof(T)));
else tmp = (t_pointer)(allocator<T>::operator new[](sizeof(T), how_many));
if(!tmp) throw(false);
p(tmp);
return tmp;
}

template <typename T> inline
void __easycode_pro::allocator<T>::deallocate(t_pointer p)
throw(bool)
{
get_address(t_type, *p);
__easycode_pro::allocator<T>::operator delete[](p, 0);
}

template <typename T>
template <typename U> inline
typename __easycode_pro::allocator<T>::t_pointer
__easycode_pro::allocator<T>::placement_allocate(U *p)
throw(bool)
{
const int __ADJUST = (sizeof(U) + 3) & ~ (3);

U * u_tmp(0);
p = allocator<U>::allocate(u_tmp, __ADJUST);
delete u_tmp;

t_pointer tmp;
tmp = (t_pointer)(allocator<T>::operator new(sizeof(t_type), p));
if(!tmp) throw(false);
return tmp;
}

template <typename T>
template <typename U> inline
void __easycode_pro::allocator<T>::placement_deallocate(U *p)
throw(bool)
{
get_address(t_type, *p);
_type_traits<U>().~_type_traits<U>();
__easycode_pro::allocator<T>::operator delete(p, p);
}
那麼我們如何分配內存呢?
自己看吧!

main()
{
using namespace __easycode_pro;
int * p;
char *c;
set_alloc_name(int);
set_alloc_name(char);

// 普通的分配
p = int_allocator::alloc(10);
c = char_allocator::alloc(20);
int_allocator::dealloc(p);
char_allocator::dealloc(c);

c = char_allocator::alloc(20);
p = int_allocator::p_alloc(c); // p 分配在 c 的空間內,邊界已經在代碼中手工調整
int_allocator::p_dealloc(p); // 釋放
}

如果您有任何意見或者疑義,可以和DarkSpy聯繫,謝謝。。。


[火星人 ] 類STL的內存分配,釋放介面已經有392次圍觀

http://coctec.com/docs/program/show-post-72077.html