new와 delete 연산자 분석

C++에서 newdelete 연산자는 객체의, 생성, 소멸, 메모리 할당 및 해제를 처리합니다.

new 연산자 동작 원리

new 연산자는 다음과 같은 두 단계로 수행됩니다:

  Point* p1 = new Point(1, 2);
  
  1. 메모리 할당: void* p = operator new(sizeof(Point))
  2. 생성자 호출: Point* p1 = new(p) Point(1, 2)

delete 연산자 동작 원리

delete 연산자도 두 단계로 수행됩니다:

  delete p1;
  
  1. 소멸자 호출: p1->~Point();
  2. 메모리 해제: operator delete(p1);

placement new

개념

placement new는 이미 할당된 메모리에 대해 생성자를 명시적으로 호출하는 기능입니다.

사용법

  // 1. 메모리만 할당
void* p1 = operator new(sizeof(Point));

// 2. 해당 메모리에 객체 생성(생성자 호출)
new(p1) Point(1, 2);  // placement new
  

이는 일반적인 new Point(1, 2)와 달리 메모리 할당과 생성자 호출을 분리합니다.

메모리 할당과 생성자 호출을 분리하는 이유

  1. vector의 resize 동작 최적화

    • 크기가 줄어들 때: capacity는 그대로 유지하고, size가 변경됨
    • 이때 초과 요소들의 소멸자만 호출해야 함
    • size가 나중에 늘어나면 생성자만 호출해야 함
  2. 메모리 관리 유연성

    • 연속된 객체 배열을 한번에 할당하고 개별적으로 초기화할 수 있음
      // 여러 Point 객체를 연속적으로 생성
    Point* p2 = static_cast<Point*>(operator new(sizeof(Point) * 3));
    
    // 각 객체마다 생성자 호출
    for (int i = 0; i < 3; ++i) {
        new(&p2[i]) Point(0, 0);
        // C++17 이후: std::construct_at(&p2[i], 0, 0);
    }