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


728x90

+ Recent posts