intel TBB 나 jemalloc 같은 memory allocator 를 써보려던 중에 기존 new, delete 를 대체하려고 operator new / delete 를 overload 해 보았다.
Global replacement
일반적으로 쓰는 new는 아래 operator 들을 overloading 하면 된다.
// replaceable allocation functions
void * operator new (std::size_t count);
void * operator new[] (std::size_t count);
void * operator new (std::size_t count, const std::nothrow_t& tag);
void * operator new[] (std::size_t count, const std::nothrow_t& tag);
// placement allocation functions
void * operator new (std::size_t count, void* ptr);
void * operator new[] (std::size_t count, void* ptr);
void * operator new (std::size_t count, user-defined-args...);
void * operator new[] (std::size_t count, user-defined-args...);
우리가 코드에 적는 new 라는 keyword 는 operator new (메모리 할당) + constructor 호출을 포함한다. operator new overloading 은 constructor 호출을 제외한 메모리 할당에 대한 부분을 재정의한다고 봐야한다.
그리고 operator new 가 재정의되면 해당 모듈의 모든 new 연산은 재정의된 연산을 타게된다. 모듈당 1번만 선언해주면 된다.
Class-specific allocation functions
operator new 를 재정의할 때 아래와 같은 짓을 하면 무한 루프를 돈다.
class CustomAlloc
{
CustomAlloc();
~CustomAlloc();
void * alloc(std::size_t count);
};
static CustomAlloc* g_alloc = nullptr;
void * operator new (std::size_t count)
{
if (g_alloc == nullptr)
{
g_alloc = new CustomAlloc; // 최초 new 호출 시에 custom allocator 생성.
// 여기서 다시 operator new가 호출되어 무한 루프 ;;;
}
return g_alloc->alloc(count);
}
이럴 때는 class-specific allocation functions을 사용하면 됨.
void* T::operator new (std::size_t count);
void* T::operator new[] (std::size_t count);
void* T::operator new (std::size_t count, user-defined-args... );
void* T::operator new[] (std::size_t count, user-defined-args... );
class CustomAlloc
{
CustomAlloc();
~CustomAlloc();
void* operator new (std::size_t count)
{
return malloc(count);
}
void * alloc(std::size_t count);
};
static CustomAlloc* g_alloc = nullptr;
void * operator new (std::size_t count)
{
if (g_alloc == nullptr)
{
g_alloc = new CustomAlloc; // 최초 new 호출 시에 custom allocator 생성.
// CustomAlloc::operator new 가 호출되어 무한 루프 아님
}
return g_alloc->alloc(count);
}
참고 :
http://en.cppreference.com/w/cpp/memory/new/operator_new
http://en.cppreference.com/w/cpp/memory/new/operator_delete