STLソースプロファイリング-カスタムallocatorの実装
3668 ワード
なぜallocatorが必要なのか
stl全体の操作オブジェクトはコンテナ内にあり、必ずスペース格納オブジェクトを構成する必要があります.通常、コンテナを使用するときにメモリがどのように割り当てられているかに関心がありません.
これはvectorヘッダファイルの定義です
vectorを定義するときにallocatorを渡さないとデフォルトのstd::allocatorが使用されることがわかります.次に、allocatorの定義仕様に従って、メモリ、共有メモリ、ディスクストレージの簡単なスペースプロファイルを実現できます.
スペースコンフィギュレータの標準インタフェース
STLの仕様に従って、allocatorの必要なインタフェース各種typedef 初期化、アドレス関連関数 構築関数
カスタムallocator
定義allocator.h
上でカスタマイズしたallocatorをコンテナに使用
出力結果
stl全体の操作オブジェクトはコンテナ内にあり、必ずスペース格納オブジェクトを構成する必要があります.通常、コンテナを使用するときにメモリがどのように割り当てられているかに関心がありません.
これはvectorヘッダファイルの定義です
template<
class T,
class Allocator = std::allocator
> class vector;
vectorを定義するときにallocatorを渡さないとデフォルトのstd::allocatorが使用されることがわかります.次に、allocatorの定義仕様に従って、メモリ、共有メモリ、ディスクストレージの簡単なスペースプロファイルを実現できます.
スペースコンフィギュレータの標準インタフェース
STLの仕様に従って、allocatorの必要なインタフェース
allocator::value_type
allocator::pointer
allocator::const_pointer
allocator::reference
allocator::const_reference
allocator::size_type
allocator::difference_type
allocator::rebind // class rebind other; typedef, allocator
// , n T , ,
pointer allocator::allocate(size_type n, const void*=0)
size_type allocator::max_size() const
pointer allocator::address(reference x) const
const_pointer allocator::address(const_reference x) const
void allocator::construct(pointer p, const T& x)
void allocator::destory(pointer p)
カスタムallocator
定義allocator.h
#include
#include
#include // for exit()
#include // for UNIX_MAX
#include
namespace test {
template
inline T* _allocate(ptrdiff_t size, T*) {
std::cout << "_allocate called" << std::endl;
set_new_handler(0);
T* tmp = (T*)(::operator new((size_t)(size * sizeof(T))));
if (NULL == tmp) {
std::cerr << "out of memory" << std::endl;
exit(0);
}
return tmp;
}
template
inline void _deallocate(T* p) {
::operator delete(p);
}
template
inline void _construct(T1* p, const T2& value) {
::new(p) T1(value);
}
template
inline void _destroy(T* p) {
p->~T();
}
template
class Allocator
{
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
template
struct rebind
{
typedef Allocator other;
};
pointer allocate(size_type n, const void* hint=0) {
return _allocate((difference_type)n, (pointer)0);
}
void deallocate(pointer p, size_type n) {
return _deallocate(p);
}
void construct(pointer p, const T& value) {
_construct(p, value);
}
void destroy(pointer p) {
_destroy(p);
}
pointer address(reference x) {
return (pointer)&x;
}
const_pointer address(const_reference x) {
return (const_pointer)&x;
}
size_type max_size() const {
return size_type(UINT_MAX/sizeof(T));
}
};
} // end of namespace
上でカスタマイズしたallocatorをコンテナに使用
#include "allocator.h"
#include
using namespace std;
int main(int argc, char const *argv[])
{
cout << "allocator test" << endl;
vector > v;
v.push_back(1);
v.push_back(2);
for (int i = 0; i < v.size(); ++i)
{
cout << v[i] << endl;
}
return 0;
}
出力結果
allocator test
_allocate called
_allocate called
1
2