Box 2 dソースコード学習メモリ管理のスタックの実現
このシリーズのブログは歪んだ45のオリジナルです.転載を歓迎します.転載する時、出典を明記します.http://blog.csdn.net/cg0206/article/details/8271251
Box 2 dには、それぞれb 2 Stock Allocatorとb 2 Grow ablockの2つのクラスがあります.
B 2 StockAllocatorは主に1ステップを実行する時にbox 2 dの必要な一時的なメモリ空間を満たすために、スタックスプリッタとしてシングルステップヒープ割り当てを防止します.
B 2 Growables Stockは主にダイナミックツリーb 2 DynancTreeの中の光投射とエリアクエリに必要な一時メモリ空間を満たすために、これはダイナミックツリーの時に詳しく研究します.
この二つの種類はどうやって実現されるかを見てみます.
1、 b 2 Stock Allocator類
まず私達はその頭のファイルb 2 StockAllocator.hを見ます.
関連する定数と構造体の定義を参照してください.
同様にFree関数も二つの場合があります.ヒープ上で申請したメモリを直接にリリースして、メモリプールで申請したメモリをメモリに戻して、リリースしなくてもいいです.
GetMaxAllocation関数は同じオブジェクトのライフサイクルに戻ります.値は増加するだけです.
2、 b 2 Grow ableStock類
このクラスの定義、実現はすべてb 2 Grow able Stock.hファイルの中にあります.
Box 2 dには、それぞれb 2 Stock Allocatorとb 2 Grow ablockの2つのクラスがあります.
B 2 StockAllocatorは主に1ステップを実行する時にbox 2 dの必要な一時的なメモリ空間を満たすために、スタックスプリッタとしてシングルステップヒープ割り当てを防止します.
B 2 Growables Stockは主にダイナミックツリーb 2 DynancTreeの中の光投射とエリアクエリに必要な一時メモリ空間を満たすために、これはダイナミックツリーの時に詳しく研究します.
この二つの種類はどうやって実現されるかを見てみます.
1、 b 2 Stock Allocator類
まず私達はその頭のファイルb 2 StockAllocator.hを見ます.
関連する定数と構造体の定義を参照してください.
//
const int32 b2_stackSize = 100 * 1024; // 100k
//
const int32 b2_maxStackEntries = 32;
//
struct b2StackEntry
{
char* data; //
int32 size; //
bool usedMalloc; //
};
コードの上にコメントがありますので、これ以上話しません.b 2 Stock Allocator類の定義を見てみましょう.//
// allocate/free 。
// allocate/free , 。
class b2StackAllocator
{
public:
/**************************************************************************
* :
* :(void)
* :
**************************************************************************/
b2StackAllocator();
/**************************************************************************
* :
* :(void)
* :
**************************************************************************/
~b2StackAllocator();
/**************************************************************************
* :
* :size :
* :
**************************************************************************/
void* Allocate(int32 size);
/**************************************************************************
* :
* :p :
* :(void)
**************************************************************************/
void Free(void* p);
/**************************************************************************
* :
* :(void)
* : 【 】
**************************************************************************/
int32 GetMaxAllocation() const;
private:
// ,
char m_data[b2_stackSize];
// ,
int32 m_index;
//
int32 m_allocation;
// 【 】
//
int32 m_maxAllocation;
//
b2StackEntry m_entries[b2_maxStackEntries];
//
int32 m_entryCount;
};
同じように多く話しません.コメントを見てください.b 2 Stock Allocatorはどのように実現されているか見てみましょう.b2StackAllocator::b2StackAllocator()
{
//
m_index = 0;
m_allocation = 0;
m_maxAllocation = 0;
m_entryCount = 0;
}
b2StackAllocator::~b2StackAllocator()
{
//
b2Assert(m_index == 0);
//
b2Assert(m_entryCount == 0);
}
以下はAllocate、Free、GetMaxAllocation関数で、コードを見ます.void* b2StackAllocator::Allocate(int32 size)
{
// ,
b2Assert(m_entryCount < b2_maxStackEntries);
//
b2StackEntry* entry = m_entries + m_entryCount;
//
entry->size = size;
// m_data ,
if (m_index + size > b2_stackSize)
{
// size ,
entry->data = (char*)b2Alloc(size);
entry->usedMalloc = true;
}
else
{
// m_data ,
// m_index
entry->data = m_data + m_index;
entry->usedMalloc = false;
m_index += size;
}
//
m_allocation += size;
//
m_maxAllocation = b2Max(m_maxAllocation, m_allocation);
//
++m_entryCount;
//
return entry->data;
}
void b2StackAllocator::Free(void* p)
{
//
b2Assert(m_entryCount > 0);
// 1,
b2StackEntry* entry = m_entries + m_entryCount - 1;
b2Assert(p == entry->data);
//
if (entry->usedMalloc)
{
// p
b2Free(p);
}
else
{
//
m_index -= entry->size;
}
//
m_allocation -= entry->size;
//
--m_entryCount;
// ,
p = NULL;
}
int32 b2StackAllocator::GetMaxAllocation() const
{
return m_maxAllocation;
}
Allocate関数については、サイズb 2_をもとに割り当てました.stackSizeのメモリプール補助配列.同時にm_も使いますindexは使用済みメモリのサイズを記録しています.メモリの中にメモリが足りないなら、スタックに申請します.そうでないとメモリの中で相応のサイズのメモリを取得します.同様にFree関数も二つの場合があります.ヒープ上で申請したメモリを直接にリリースして、メモリプールで申請したメモリをメモリに戻して、リリースしなくてもいいです.
GetMaxAllocation関数は同じオブジェクトのライフサイクルに戻ります.値は増加するだけです.
2、 b 2 Grow ableStock類
このクラスの定義、実現はすべてb 2 Grow able Stock.hファイルの中にあります.
// N
// ,
template <typename T, int32 N>
class b2GrowableStack
{
public:
/**************************************************************************
* : ,
* :(void)
* :(void)
**************************************************************************/
b2GrowableStack()
{
m_stack = m_array;
m_count = 0;
m_capacity = N;
}
/**************************************************************************
* : ,
* :(void)
* :(void)
**************************************************************************/
~b2GrowableStack()
{
if (m_stack != m_array)
{
b2Free(m_stack);
m_stack = NULL;
}
}
/**************************************************************************
* :
* :element :
* :(void)
**************************************************************************/
void Push(const T& element)
{
//
if (m_count == m_capacity)
{
// old
T* old = m_stack;
// 2
m_capacity *= 2;
// , m_stack
m_stack = (T*)b2Alloc(m_capacity * sizeof(T));
// m_stack
std::memcpy(m_stack, old, m_count * sizeof(T));
if (old != m_array)
{
// old
b2Free(old);
}
}
// ,
m_stack[m_count] = element;
++m_count;
}
/**************************************************************************
* :
* :(void)
* :
**************************************************************************/
T Pop()
{
//
b2Assert(m_count > 0);
// ,
--m_count;
return m_stack[m_count];
}
/**************************************************************************
* :
* :(void)
* :
**************************************************************************/
int32 GetCount()
{
return m_count;
}
private:
//
T* m_stack;
//
T m_array[N];
//
int32 m_count;
//
int32 m_capacity;
};
このクラスはテンプレートクラスで、すべての要素のタイプとスタックの大きさは使用時に自分で定義し、同じメモリプールすなわち補助配列によって模擬されたスタックと出スタックです.異なるところは、メモリが足りない場合、b 2 GrowbaleStockは、元の倍の容量が大きい新しいメモリプールを再申請し、古いメモリプールの内容を新しいメモリにコピーして、補助配列以外の古いメモリプールを同時に開放しますが、何度も拡張しておくと、一定の影響があります.使う前に必要なメモリの大きさを見積もっておいたほうがいいです.push/pop関数については,配列シミュレーションの輸出入スタックを用いた.他には何も言いません.