개념 개요
new와 delete는 C++ 표준에 정의된 연산자로, 동적 메모리 할당과 해제를 담당한다. new는 힙 영역(heap)에서 객체나 배열을 생성하고, 해당 객체의 주소를 반환한다. delete는 new에 의해 할당된 메모리를 반환하고, 객체의 소멸자를 호출한다.
주요 특징
| 특징 | new |
delete |
|---|---|---|
| 동작 | 힙 영역에서 지정된 타입 또는 타입 배열을 할당 | new로 할당된 메모리를 해제 |
| 반환값 | 할당된 객체(또는 배열)의 포인터 | 반환값 없음 |
| 예외 | 할당 실패 시 std::bad_alloc 예외 발생 (예외를 비활성화한 경우 nullptr 반환) |
해제 중 오류가 발생하면 정의되지 않은 동작(UB) |
| 소멸자 호출 | 할당 시 자동 호출되지 않음(단일 객체 생성 시 생성자 호출) | 포인터가 가리키는 객체의 소멸자를 호출 후 메모리 반환 |
| 배열 형식 | new Type[n] (배열 할당) |
delete[] ptr (배열 해제) |
| 메모리 정렬 | 구현에 따라 기본 정렬을 따름(필요 시 alignas 사용) |
동일한 정렬 요구사항을 만족하는 메모리 해제 |
문법
// 단일 객체
Type* p = new Type(args...); // 생성자 호출
// 배열
Type* arr = new Type[count]; // 기본 생성자 호출(또는 POD인 경우 초기화되지 않음)
// 해제
delete p; // 소멸자 호출 후 메모리 반환
delete[] arr; // 배열 소멸자 호출 후 메모리 반환
new연산자는operator new함수를 내부적으로 호출한다. 표준에서는 전역operator new(std::size_t)와operator new[](std::size_t)를 제공한다. 사용자는 이 함수를 오버로드하여 커스텀 할당 전략을 정의할 수 있다.delete연산자는 대응되는operator delete와operator delete[]를 호출한다. 오버로드된 경우, 동일한 형태(단일/배열)와 일치해야 한다.
예외 처리
try {
Widget* w = new Widget(); // 할당 실패 시 std::bad_alloc 발생
} catch (const std::bad_alloc& e) {
// 예외 처리
}
예외를 비활성화하려면 std::nothrow를 사용할 수 있다.
Widget* w = new (std::nothrow) Widget(); // 할당 실패 시 nullptr 반환
주의점
new와delete는 반드시 짝을 이루어야 한다. 짝이 맞지 않을 경우 메모리 누수 또는 이중 해제가 발생한다.delete에nullptr를 전달하면 아무 동작도 수행되지 않는다(안전).new와delete는 같은 할당자/해제자를 사용해야 한다. 전역operator new와 사용자 정의operator delete가 혼용되면 정의되지 않은 동작이 발생한다.- 배열을
new로 할당했지만delete(단일)로 해제하면 정의되지 않은 동작이다. 마찬가지로new[]와delete[]도 짝을 맞춰야 한다.
표준 규격
- C++ 표준(ISO/IEC 14882)에서
new와delete는 5.3.4(동적 메모리 할당) 및 5.3.5(동적 메모리 해제) 절에 정의돼 있다. - C++17부터
std::aligned_alloc과std::aligned_new같은 정렬 지원이 추가되었으며, C++20에서는operator new의nothrow_t및align_val_t오버로드가 공식화되었다.
관련 연산자 및 함수
| 이름 | 설명 |
|---|---|
std::nothrow |
할당 실패 시 예외 대신 nullptr을 반환하도록 new에 전달 |
std::unique_ptr<T> |
RAII 기반 자동 해제를 제공, new와 delete 사용을 대체 가능 |
std::shared_ptr<T> |
공유 소유권을 제공, 내부적으로 delete를 호출 |
operator new / operator delete |
전역 또는 클래스 별 오버로드 가능한 메모리 할당/해제 함수 |
placement new |
기존 메모리 영역에 객체를 생성(소멸자는 별도 호출 필요) |
역사 및 어원
new와delete는 C++ 초기 설계 시점(1980년대 후반)부터 포함되었다. C 언어의malloc/free와 달리 객체 생성·소멸자를 자동으로 연계하도록 설계되었다.- 용어 자체는 영어 동사 ‘new(새로운)’와 ‘delete(삭제하다)’에서 차용된 것으로, 메모리 관리 연산자를 직관적으로 표현한다는 의도다.
실제 사용 예시
#include <iostream>
class Node {
public:
int value;
Node(int v) : value(v) { std::cout << "Node constructed
"; }
~Node() { std::cout << "Node destroyed
"; }
};
int main() {
Node* p = new Node(10); // 생성자 호출, 메모리 할당
std::cout << p->value << '
';
delete p; // 소멸자 호출, 메모리 반환
// 배열
Node* arr = new Node[3] { {1}, {2}, {3} };
delete[] arr;
return 0;
}
요약
new와 delete는 C++ 표준에 포함된 핵심 메모리 관리 연산자로, 동적 객체 생성을 위한 할당과 소멸자를 포함한 해제를 담당한다. 올바른 짝 맞춤, 예외 처리, 그리고 필요 시 사용자 정의 operator new/delete를 통해 다양한 메모리 관리 전략을 구현할 수 있다.
(본 내용은 ISO/IEC 14882 표준 및 널리 인정받는 C++ 교과서·문서에 기반함)