프로그래밍C++ 개발자

'placement new'가 C++에서 무엇인가요? 이 메커니즘은 무엇을 위해 어떻게 사용되나요?

Hintsage AI 어시스턴트로 면접 통과

답변

placement new는 C++에서의 특별한 형태의 new 연산자입니다. 이는 이미 할당된 메모리 영역 내의 특정 주소에 객체를 배치할 수 있게 해줍니다. 일반적으로 메모리를 수동으로 관리하는 데 사용되며, 할로케이터, 객체 풀링, 고정된 버퍼에 대한 직렬화 작업의 기초가 됩니다.

구문:

#include <new> void* memory = malloc(sizeof(MyClass)); MyClass* obj = new (memory) MyClass(args...); // memory 주소에서 생성자 호출

여기서 메모리는 따로 할당되며 (예: malloc 또는 할로케이터를 통해), 이후 이 메모리에서 클래스의 생성자가 호출됩니다. 명시적으로 소멸자를 호출하는 것을 잊지 마세요:

obj->~MyClass(); free(memory);

장점:

  • 사용자 정의 할로케이터를 구현할 수 있습니다.
  • 메모리 재할당 비용이 줄어듭니다.
  • 표준 할로케이터를 호출하지 않으므로 메모리 관리에 대한 제어력이 있습니다.

함정 질문

'placement new'를 사용해 같은 메모리 블록에 여러 객체를 연속적으로 배치할 수 있나요? 그리고 그로 인해 어떤 결과가 초래되나요?

자주 잘못된 답변 — 이전 상태에 신경 쓰지 않고 메모리에 새로운 객체를 배치할 수 있습니다. 실제로는 같은 메모리 영역에 이전 객체 위에 새로운 객체를 배치할 경우 소멸자를 호출하지 않으면 리소스 누수가 발생하며, 이후 소멸자를 호출하면 정의되지 않은 동작(UB)이 발생합니다.

예:

void* place = malloc(sizeof(A)); A* a = new (place) A(); B* b = new (place) B(); // 객체 A는 파괴되지 않음! UB!

주제에 대한 세부 사항을 모르는 실수의 실제 예


이야기

고부하 시스템에서 개발자는 malloc + placement new를 통해 객체 풀을 구현했지만 객체를 풀에 반환할 때 소멸자를 호출하는 것을 잊었습니다. 결국 리소스(객체 내부의 시스템 디스크립터)는 해제되지 않아 리소스 누수와 서버 "정지" 현상이 발생했습니다.



이야기

이진 데이터 직렬화를 위한 프로젝트에서 버퍼와 placement new를 사용해 제자리에 객체를 디코딩했습니다. 그러나 배치 전에 메모리를 0으로 초기화하는 것을 잊어버려 초기화되지 않은 데이터를 읽게 되고 POD 구조체 작업 중 이상한 버그가 발생했습니다.



이야기

하나의 모듈은 미리 할당된 블록 내에서 객체 배열 배치를 placement new를 통해 마이그레이션했습니다. 클래스 내에 새로운 비트리비얼 소멸자 멤버를 추가한 후, 정리 시 각 요소에 대해 소멸자를 명시적으로 호출해야 한다는 것을 잊어버려 프로그램이 예외적으로 종료되었습니다.