EASTLによるアロケータはステートフルであり、コンテナのインスタンスにバインドされています。これらは、インスタンス・レベルで定義されている意味:
何EASTLことが唯一のアロケータクラスインターフェースであり、それは すべてのコンテナで使用されるより身近なメモリ割り当てパターン を使用することです。さらに、EASTLコンテナでは、 アロケータにアクセスし、それらの名前を付けたり、名前を付けたり、変更したりすることができます。
EASTLは、コンテナスワップおよび割り当て操作中にコンテナ間でアロケータをコピーしないように選択しました。つまり、 コンテナAがその内容をコンテナBと交換すると、両方のコンテナ は元のアロケータを保持します。同様に、コンテナAを コンテナBに割り当てると、コンテナBは元のアロケータを保持します。 同等のコンテナは、operator ==;によってレポートする必要があります。 EASTL は、アロケータが等しい場合はスマートスワップを行い、それ以外の場合はブルートフォーススワップ を実行します。 https://github.com/questor/eastl/blob/master/doc/EASTL%20Design.html
から
だから私はアロケータクラスにメンバーを追加し、次のように、その内部にメモリカウントを追跡します:
#ifndef EASTL_CUSTOM_ALLOCATOR_H_
#define EASTL_CUSTOM_ALLOCATOR_H_
#include "new_implementation.hpp"
#include <EASTL/list.h>
#include <iostream>
#define DEBUG_MACRO
class EASTL_CustomAllocator {
public:
EASTL_CustomAllocator(const char* pName = EASTL_NAME_VAL(EASTL_ALLOCATOR_DEFAULT_NAME))
: m_pName(pName), m_totalAmountOfBytesAllocated(0) {
#ifdef DEBUG_MACRO
std::cout << m_pName << ": default construct allocator" << std::endl;
#endif
}
EASTL_CustomAllocator(const EASTL_CustomAllocator& x)
: m_pName(x.m_pName),
m_totalAmountOfBytesAllocated(x.m_totalAmountOfBytesAllocated) {
#ifdef DEBUG_MACRO
std::cout << m_pName << ": copy construct allocator" << std::endl;
#endif
}
EASTL_CustomAllocator(const EASTL_CustomAllocator& x, const char* pName)
: m_pName(pName),
m_totalAmountOfBytesAllocated(x.m_totalAmountOfBytesAllocated) {
#ifdef DEBUG_MACRO
std::cout << m_pName << ": copy construct allocator" << std::endl;
#endif
}
EASTL_CustomAllocator& operator=(const EASTL_CustomAllocator& x) {
#ifdef DEBUG_MACRO
std::cout << m_pName << ": copy assignment" << std::endl;
#endif
m_pName = x.m_pName;
m_totalAmountOfBytesAllocated = x.m_totalAmountOfBytesAllocated;
return *this;
}
void* allocate(size_t num_of_bytes, int flags = 0) {
m_totalAmountOfBytesAllocated += num_of_bytes;
void* p = ::new((char*)0, flags, 0, (char*)0, 0) char[num_of_bytes];
#ifdef DEBUG_MACRO
std::cout << m_pName << ": allocate " << num_of_bytes << " bytes" << " at: " << (void*) p << std::endl;
#endif
return p;
}
void* allocate(size_t num_of_bytes, size_t alignment, size_t offset, int flags = 0) {
m_totalAmountOfBytesAllocated += num_of_bytes;
void* p = ::new(alignment, offset, (char*)0, flags, 0, (char*)0, 0) char[num_of_bytes];
#ifdef DEBUG_MACRO
std::cout << m_pName << ": allocate " << num_of_bytes << " bytes" << " at: " << (void*) p << std::endl;
#endif
return p;
}
void deallocate(void* p, size_t num_of_bytes) {
m_totalAmountOfBytesAllocated -= num_of_bytes;
#ifdef DEBUG_MACRO
std::cout << m_pName << ": deallocate " << num_of_bytes << " bytes" << " at: " << (void*) p << std::endl;
#endif
delete[](char*)p;
}
const char* get_name() const {
return m_pName;
}
void set_name(const char* pName) {
m_pName = pName;
}
size_t get_totalAmountOfBytesAllocated() const {
return m_totalAmountOfBytesAllocated;
}
protected:
const char* m_pName; // Debug name, used to track memory.
size_t m_totalAmountOfBytesAllocated; // keeps track of the memory currently allocated
};
bool operator==(const EASTL_CustomAllocator& a, const EASTL_CustomAllocator& b) {
if (&a == &b) {
return true; // allocator a and b are equal if they are the same
}
else {
return false; // otherwhise, return false, because the state m_totalAmountOfBytesAllocated needs to be increased/decreased on splice and swap
}
}
bool operator!=(const EASTL_CustomAllocator& a, const EASTL_CustomAllocator& b) {
return false;
}
#endif /* EASTL_CUSTOM_ALLOCATOR_H_ */
はにテンプレートパラメータとしてそのカスタムアロケータ型を渡します以下のようなeastlコンテナ(また、構築時にユーザ定義の名前でインスタンスを設定することもできますし、後でset_allocator()で設定することもできます)。
しかし、デバッグ機能をどのように使用するのかはわかりません。
たとえば、アロケータは、要求よりも大きなブロックを割り当て、最初に名前(および/または追加情報)を隠し、ブロックの残りの部分を指すポインタを返すことができます。 Deallocatorは、この情報を、それが与えられたポインタからの負のオフセットで見つける。 –