C++ placement new란?
간단히 말해, placement new는 이미 할당되어 있는 메모리 공간 위에 새로운 객체를 "생성"할 수 있게 해주는 C++의 기능입니다. 새로 메모리를 할당하지 않고 기존에 확보된 메모리를 그대로 재사용하기 때문에 불필요한 할당·해제 오버헤드를 없앨 수 있어 성능 최적화에 매우 유용합니다.
기본 문법은 다음과 같습니다.
new (address) (type) initializer즉, 생성할 객체의 타입과 함께 해당 객체가 만들어질 메모리 주소를 직접 지정할 수 있습니다.
예제 코드
#include <iostream>
using namespace std;
int main() {
int a = 5;
cout << "a = " << a << endl;
cout << "&a = " << &a << endl;
// placement new를 사용해 변수 a의 메모리에 값 10을 생성
int *m = new (&a) int(10);
cout << "\nplacement new 사용 후:" << endl;
cout << "a = " << a << endl;
cout << "m = " << m << endl;
cout << "&a = " << &a << endl;
return 0;
}실행 결과
a = 5 &a = 0x60ff18 placement new 사용 후: a = 10 m = 0x60ff18 &a = 0x60ff18
동작 원리
위 예제에서 new (&a) int(10)는 변수 a가 차지하고 있는 메모리 주소에 값 10을 가진 새로운 int 객체를 생성합니다. 그 결과 변수 a의 값이 5에서 10으로 바뀌고, 포인터 m은 &a와 정확히 같은 주소를 가리키게 됩니다. 즉, 새 메모리를 요청하는 것이 아니라 기존 메모리 위치에 객체를 덮어쓰듯 생성하는 것입니다.
사용 시 주의 사항
placement new를 사용할 때는 몇 가지 유의해야 할 점이 있습니다.
- 헤더 포함: placement new를 사용하려면
#include <new>헤더를 포함해야 합니다. - delete 사용 금지: placement new로 생성한 객체는 일반적인
delete로 해제하면 안 됩니다. 해당 메모리는 스택 등 다른 영역에서 이미 관리되고 있기 때문에 프로그램이 비정상 종료될 수 있습니다. - 소멸자 명시적 호출: 객체 사용을 마친 후에는
m->~int();처럼 소멸자를 직접 호출하여 리소스를 정리해야 합니다. - 메모리 정렬: 지정한 주소가 해당 타입의 정렬(alignment) 요구 조건을 충족해야 정의되지 않은 동작을 피할 수 있습니다.
이러한 특성 덕분에 placement new는 메모리 풀(memory pool), 커스텀 할당자, 임베디드 시스템처럼 메모리 관리를 세밀하게 제어해야 하는 환경에서 널리 활용됩니다.