delete expression
new-expression 으로 이전에 할당된 객체를 파괴하고 확보된 메모리 영역을 해제합니다.
목차 |
구문
::
(선택적)
delete
표현식
|
(1) | ||||||||
::
(선택적)
delete[]
표현식
|
(2) | ||||||||
| expression | - |
다음 중 하나:
|
설명
expression 으로 평가된 포인터(가능한 변환 후)를 ptr 로 지정합니다.
- 널 포인터,
- new-expression 으로 생성된 비배열 객체에 대한 포인터, 또는
- new-expression 으로 생성된 비배열 객체의 기반 서브객체에 대한 포인터.
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 을 참조하십시오):
|
(C++20부터) |
|
(C++17부터) |
- 찾은 할당 해제 함수가 클래스별(class-specific)인 경우, 크기 인식 없는(size-unaware) 클래스별 할당 해제 함수( std::size_t 타입의 매개변수가 없는)가 크기 인식 있는(size-aware) 클래스별 할당 해제 함수( 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부터) |
키워드
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 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 |
할당 해제 함수와 소멸자에 대한 접근 제어가
어떻게 수행되는지 불분명했음 |
명확히 규정됨 |