Namespaces
Variants

delete expression

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
delete expression
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

new-expression 으로 이전에 할당된 객체를 파괴하고 확보된 메모리 영역을 해제합니다.

목차

구문

:: (선택적) delete 표현식 (1)
:: (선택적) delete[] 표현식 (2)
expression - 다음 중 하나:
1) new-expression 으로 생성된 하나의 비배열 객체를 파괴합니다.
2) new[]-표현식 으로 생성된 배열을 파괴합니다.

설명

expression 으로 평가된 포인터(가능한 변환 후)를 ptr 로 지정합니다.

1) ptr 는 다음 중 하나여야 합니다
  • 널 포인터,
  • new-expression 으로 생성된 비배열 객체에 대한 포인터, 또는
  • new-expression 으로 생성된 비배열 객체의 기반 서브객체에 대한 포인터.
ptr 이 가리키는 타입은 객체의 타입(혹은 베이스 서브오브젝트의 타입)과 유사(similar) 해야 합니다. 만약 ptr 이 다른 것이라면, 예를 들어 new-expression 의 배열 형태로 얻은 포인터인 경우를 포함하여, 이때의 동작은 정의되지 않음(undefined) 입니다.
2) ptr 는 널 포인터이거나, 이전에 배열 형태의 new-expression 으로 얻은 값이어야 하며, 해당 allocation function 이 비-할당 형태(즉, 오버로드 (10) )가 아니어야 합니다.
ptr 가 가리키는 타입은 배열 객체의 요소 타입과 유사(similar) 해야 합니다. 만약 ptr 이 다른 것이라면, 예를 들어 new-expression 의 비-배열 형태로 얻은 포인터인 경우를 포함하여, 그 동작은 정의되지 않음(undefined) 입니다.

delete-표현식의 결과는 항상 void 타입을 가집니다.

삭제 지점에서 객체가 불완전한 클래스 타입인 경우, 완전한 클래스가 non-trivial destructor나 deallocation function을 가지고 있다면, 그 동작은 정의되지 않음 (until C++26) 프로그램은 ill-formed (since C++26) .

만약 ptr 이 null 포인터가 아니고 할당 해제 함수 가 destroying delete가 아닌 경우 (C++20부터) , delete-expression은 파괴되는 객체 또는 배열의 각 요소(배열의 마지막 요소부터 첫 번째 요소 순서로)에 대한 destructor (존재하는 경우)를 호출합니다. destructor는 delete-expression이 나타나는 지점에서 접근 가능 해야 합니다.

그 후, 어떤 소멸자에서 예외가 발생했는지 여부와 관계없이, delete-표현식은 할당 해제 함수 를 호출합니다: operator delete (첫 번째 버전) 또는 operator delete [ ] (두 번째 버전) , 단, 일치하는 new-표현식이 다른 new-표현식과 결합된 경우는 제외 (C++14부터) .

할당 해제 함수의 이름은 조회 ptr 이 가리키는 객체의 동적 타입 범위에서 이루어지며, 이는 클래스별 할당 해제 함수가 존재할 경우 전역 함수보다 먼저 발견됨을 의미합니다. 만약 :: 가 delete 표현식에 존재한다면, 이 조회에서는 전역 네임스페이스만 검사됩니다. 어떤 경우든 일반적인 할당 해제 함수 선언이 아닌 다른 선언들은 모두 무시됩니다.

어떤 할당 해제 함수가 발견되면, 호출될 함수는 다음과 같이 선택됩니다 (이 함수들과 그 효과에 대한 더 자세한 설명은 deallocation function 을 참조하십시오):

  • 파괴적 삭제(deleting delete) 함수가 하나라도 존재할 경우, 모든 비파괴적 삭제(non-destroying delete) 함수는 무시됩니다.
(C++20부터)
  • 타입의 정렬 요구사항이 __STDCPP_DEFAULT_NEW_ALIGNMENT__ 를 초과하는 경우, 정렬 인지 할당 해제 함수(alignment-aware deallocation functions)( std::align_val_t 타입의 매개변수를 가짐)가 우선적으로 선택됩니다. 다른 타입의 경우, 정렬 비인지 할당 해제 함수(alignment-unaware deallocation functions)( std::align_val_t 타입의 매개변수를 가지지 않음)가 우선적으로 선택됩니다.
  • 둘 이상의 우선 함수가 발견된 경우, 다음 단계에서는 우선 함수만 고려됩니다.
  • 우선 함수가 발견되지 않은 경우, 다음 단계에서는 비우선 함수들이 고려됩니다.
  • 단 하나의 함수만 남은 경우, 해당 함수가 선택됩니다.
(C++17부터)
  • 찾은 할당 해제 함수가 클래스별(class-specific)인 경우, 크기 인식 없는(size-unaware) 클래스별 할당 해제 함수( std::size_t 타입의 매개변수가 없는)가 크기 인식 있는(size-aware) 클래스별 할당 해제 함수( std::size_t 타입의 매개변수가 있는)보다 우선적으로 선택됩니다.
  • 그렇지 않으면, 조회가 전역 범위에 도달하며:
  • 타입이 완전하고(배열 형태에만 해당) 피연산자가 비트리비얼 소멸자를 가진 클래스 타입에 대한 포인터이거나 이를 (다차원일 수 있는) 배열인 경우, 전역 크기 인지 할당 해제 함수( std::size_t 타입의 매개변수를 가짐)가 선택됩니다.
  • 그렇지 않으면, 전역 크기 인지 할당 해제 함수( std::size_t 타입의 매개변수를 가짐) 또는 전역 크기 비인지 할당 해제 함수( std::size_t 타입의 매개변수를 가지지 않음) 중 어느 것이 선택되는지 명시되지 않습니다.
(C++14부터)

선택된 할당 해제 함수는 delete 표현식이 나타나는 지점에서 접근 가능 해야 합니다. 단, 할당 해제 함수가 동적 타입 가상 소멸자 정의 지점에서 선택되는 경우는 예외입니다.

회수될 저장소 블록에 대한 포인터는 위 과정에서 선택된 할당 해제 함수 에 첫 번째 인수로 전달됩니다. 블록의 크기는 선택적 std::size_t 인수로 전달됩니다. 정렬 요구사항은 선택적 std::align_val_t 인수로 전달됩니다. (C++17부터)

만약 ptr 가 널 포인터 값인 경우, 소멸자는 호출되지 않으며, 할당 해제 함수는 호출될 수도 있고 호출되지 않을 수도 있습니다(이는 명시되지 않음). 그러나 기본 할당 해제 함수들은 널 포인터가 전달될 경우 아무 작업도 수행하지 않음이 보장됩니다.

만약 ptr new 로 할당된 객체의 기본 클래스 서브객체를 가리키는 포인터라면, 기본 클래스의 소멸자는 virtual 이어야 하며, 그렇지 않을 경우 동작은 정의되지 않습니다.

참고 사항

void 포인터는 객체 타입에 대한 포인터가 아니기 때문에 삭제될 수 없습니다.

delete 키워드 뒤에 오는 대괄호 쌍은 항상 배열 형태의 delete-표현식으로 해석되므로, delete 바로 뒤에 빈 캡처 목록을 가진 lambda-expression 이 올 경우 반드시 괄호로 묶어야 합니다.

// delete []{ return new int; }(); // parse error
delete ([]{ return new int; })();  // OK
(C++11부터)

키워드

delete

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
CWG 288 C++98 첫 번째 형식의 경우 피연산자의 정적 타입이
동적 타입과 비교되었음
삭제될 객체의 정적 타입을
동적 타입과 비교
CWG 353 C++98 소멸자가 예외를 발생시키는 경우 할당 해제 함수가
호출되는지 여부가 명시되지 않았음
항상 호출됨
CWG 599 C++98 첫 번째 형식이 함수 포인터를 포함한
모든 타입의 널 포인터를 취할 수 있었음
객체 타입에 대한 포인터를 제외하고,
다른 모든 포인터 타입은 거부됨
CWG 1642 C++98 expression 이 포인터 좌측값일 수 있었음 허용되지 않음
CWG 2474 C++98 유사하지만 다른 타입의 객체에 대한 포인터를
삭제하면 정의되지 않은 동작이 발생했음
올바르게 정의됨
CWG 2624 C++98 비할당
operator new [ ] 로부터 얻은 포인터를 delete [ ] 에 전달할 수 있었음
금지됨
CWG 2758 C++98 할당 해제 함수와 소멸자에 대한 접근 제어가
어떻게 수행되는지 불분명했음
명확히 규정됨

참고 항목