본문 바로가기
Object Oriented Programming(C++)/Effective C++

Effective C++ | 항목 52 placement new를 작성한다면 placement delete도 작성하자

by continue96 2024. 8. 8.

항목 52 placement new를 작성한다면 placement delete도 작성하자

52.1 placement new

 52.1.1 placement new

  • placement new 다른 매개변수를 추가로 전달하는 operator new 함수를 말한다.
    • <new> 헤더 파일을 포함하면 void* 포인터를 추가로 받는 표준 placement new를 사용할 수 있다.
// 어떤 객체를 생성할 메모리 위치를 나타내는 포인터를 매개변수로 받는 placement new입니다.
// C++ 표준 라이브러리에 정의되어 있습니다.
void* operator new(std::size_t _iSize, void* _pMemory) throw();

 

 52.1.2 placement new 예외 처리

// 기본 operator new
void* operator new(std::size_t _iSize) throw(std::bad_alloc);

// 기본 operator delete는 기본 operator new에 대응됩니다.
void* operator delete(void* _pMemory) throw();

class Widget
{
public:
	// 비표준 placement new
	static void* operator new(std::size_t _iSize, std::ostream& _osLog) throw(std::bad_alloc);

	// 비표준 placement delete는 비표준 placement new에 대응하도록 작성합니다.
	static void operator delete(void* _pMemory, std::ostream& _osLog) throw();
};

// 기본 operator new로 할당합니다.
Widget* pWidget = new Widget;

// placement new로 할당합니다.
Widget* pWidget = new (std::cerr) Widget;

 

  • new 표현식을 작성하면 operator new 함수와 Widget 생성자가 호출된다.
  • Widget 생성자에서 예외가 발생하는 경우, operator new로 할당한 메모리는 (사용자가 아닌) 런타임 시스템에서 해제해야 한다.
    • 이때, 런타임 시스템은 operator new 함수에 대응되는, 즉 전달받는 매개변수 개수와 타입이 같은 operator delete 함수를 호출한다.
    • 그러한 operator delete가 없는 경우, 어떠한 operator delete도 호출하지 않는다.
    • 따라서 placement new를 작성한다면 메모리가 누수되지 않도록 placement delete를 마련해야 한다.
  •  Widget 생성자에서 예외가 발생하지 않는 경우, operator new로 할당한 메모리는 기본 operator delete로 해제한다.
    • 따라서 placement new를 작성한다면 기본 operator delete도 마련해야 한다.

 

52.2 operator new 유효 범위

  • 클래스에 정의한 operator new가 전역 operator new를 가리지 않도록 주의해야 한다.
    • 기본 클래스에 정의된 operator new는 전역 operator new를 가린다.
    • 자식 클래스에 정의된 operator new는 전역 operator new와 기본 클래스 operator new도 가린다.
// 전역 operator new들
// 기본 operator new
void* operator new(std::size_t) throw(std::bad_alloc);

// placement new
void* operator new(std::size_t, void*) throw();

// nothrow new
void* operator new(std::size_t, const std::nothrow_t&) throw();

 

 

NOTE
① placement new를 만들 때, 이 함수와 짝 맞는 placement delete를 만들자.
② placement new, placement delete 함수를 선언할 때, 표준 operator new, operator delete가 가려지지 않도록 주의하자.

댓글