Namespaces
Variants

operator delete , operator delete[]

From cppreference.net
< cpp ‎ | memory ‎ | new
Utilities library
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
헤더 파일에 정의됨 <new>
대체 가능한 일반 할당 해제 함수
(1)
void operator delete ( void * ptr ) throw ( ) ;
(C++11 이전)
void operator delete ( void * ptr ) noexcept ;
(C++11 이후)
(2)
void operator delete [ ] ( void * ptr ) throw ( ) ;
(C++11 이전)
void operator delete [ ] ( void * ptr ) noexcept ;
(C++11 이후)
void operator delete ( void * ptr, std:: align_val_t al ) noexcept ;
(3) (C++17부터)
void operator delete [ ] ( void * ptr, std:: align_val_t al ) noexcept ;
(4) (C++17부터)
void operator delete ( void * ptr, std:: size_t sz ) noexcept ;
(5) (C++14부터)
void operator delete [ ] ( void * ptr, std:: size_t sz ) noexcept ;
(6) (C++14부터)
void operator delete ( void * ptr, std:: size_t sz,
std:: align_val_t al ) noexcept ;
(7) (C++17부터)
void operator delete [ ] ( void * ptr, std:: size_t sz,
std:: align_val_t al ) noexcept ;
(8) (C++17부터)
대체 가능한 배치 해제 함수
(9)
void operator delete ( void * ptr, const std:: nothrow_t & tag ) throw ( ) ;
(C++11 이전)
void operator delete ( void * ptr, const std:: nothrow_t & tag ) noexcept ;
(C++11 이후)
(10)
void operator delete [ ] ( void * ptr, const std:: nothrow_t & tag ) throw ( ) ;
(C++11 이전)
void operator delete [ ] ( void * ptr, const std:: nothrow_t & tag ) noexcept ;
(C++11 이후)
void operator delete ( void * ptr, std:: align_val_t al,
const std:: nothrow_t & tag ) noexcept ;
(11) (C++17 이후)
void operator delete [ ] ( void * ptr, std:: align_val_t al,
const std:: nothrow_t & tag ) noexcept ;
(12) (C++17 이후)
비할당 배치 해제 함수
(13)
void operator delete ( void * ptr, void * place ) throw ( ) ;
(C++11 이전)
void operator delete ( void * ptr, void * place ) noexcept ;
(C++11 이후)
(14)
void operator delete [ ] ( void * ptr, void * place ) throw ( ) ;
(C++11 이전)
void operator delete [ ] ( void * ptr, void * place ) noexcept ;
(C++11 이후)
사용자 정의 배치 해제 함수
void operator delete ( void * ptr, args... ) ;
(15)
void operator delete [ ] ( void * ptr, args... ) ;
(16)
클래스별 일반 할당 해제 함수
void T :: operator delete ( void * ptr ) ;
(17)
void T :: operator delete [ ] ( void * ptr ) ;
(18)
void T :: operator delete ( void * ptr, std:: align_val_t al ) ;
(19) (C++17부터)
void T :: operator delete [ ] ( void * ptr, std:: align_val_t al ) ;
(20) (C++17 이후)
void T :: operator delete ( void * ptr, std:: size_t sz ) ;
(21)
void T :: operator delete [ ] ( void * ptr, std:: size_t sz ) ;
(22)
void T :: operator delete ( void * ptr, std:: size_t sz, std:: align_val_t al ) ;
(23) (C++17부터)
void T :: operator delete [ ] ( void * ptr, std:: size_t sz, std:: align_val_t al ) ;
(24) (C++17부터)
클래스별 배치 해제 함수
void T :: operator delete ( void * ptr, args... ) ;
(25)
void T :: operator delete [ ] ( void * ptr, args... ) ;
(26)
클래스별 일반 파괴적 할당 해제 함수
void T :: operator delete ( T * ptr, std:: destroying_delete_t ) ;
(27) (C++20 이후)
void T :: operator delete ( T * ptr, std:: destroying_delete_t ,
std:: align_val_t al ) ;
(28) (C++20 이후)
void T :: operator delete ( T * ptr, std:: destroying_delete_t , std:: size_t sz ) ;
(29) (C++20 이후)
void T :: operator delete ( T * ptr, std:: destroying_delete_t ,
std:: size_t sz, std:: align_val_t al ) ;
(30) (C++20 이후)

이전에 일치하는 operator new 또는 operator new[] 에 의해 할당된 저장 공간을 해제합니다. 이러한 해제 함수들은 delete delete [ ] 표현식 에 의해, 그리고 placement new 표현식 에 의해 동적 저장 기간을 가진 객체들을 파괴한 후(또는 생성에 실패한 후) 메모리를 해제하기 위해 호출됩니다. 또한 일반 함수 호출 구문을 사용하여 호출될 수도 있습니다.

1-12) Replaceable 할당 해제 함수들. 표준 라이브러리는 이러한 함수들에 대한 기본 구현을 제공하며, 기본 구현의 효과에 대해서는 아래 를 참조하십시오.
1-8) delete delete [ ] 표현식에 의해 호출됩니다. null이 아닌 ptr 을 무효화합니다.
9-12) 배치 new 표현식에 의해 초기화 실패 시 호출됩니다. operator delete [ ] 는 null이 아닌 모든 ptr 을 무효화합니다.
만약 ptr 이 널 포인터가 아니고 다음 조건 중 하나를 만족할 경우, 동작은 정의되지 않음:
  • operator delete 의 경우, ptr 의 값이 이전에 (대체되었을 수 있는) operator new ( std:: size_t ) 호출로 할당된 메모리 블록의 주소를 나타내지 않거나 (오버로드 (1,5,9) 에 대해), 또는 operator new ( std:: size_t , std:: align_val_t ) 호출로 할당된 메모리 블록의 주소를 나타내지 않으며 (오버로드 (3,7,11) 에 대해), 이 사이에 operator delete 호출로 무효화되지 않은 경우.
  • operator delete [ ] 의 경우, ptr 의 값이 이전에 (대체되었을 수 있는) operator new [ ] ( std:: size_t ) 호출로 할당된 메모리 블록의 주소를 나타내지 않거나 (오버로드 (2,6,10) 에 대해), 또는 operator new [ ] ( std:: size_t , std:: align_val_t ) 호출로 할당된 메모리 블록의 주소를 나타내지 않으며 (오버로드 (4,8,12) 에 대해), 이 사이에 operator delete [ ] 호출로 무효화되지 않은 경우.
13,14) 표현식의 초기화 과정 중 어떤 부분이 예외를 던져 종료될 때 비할당 배치 할당 함수 를 호출한 배치 new 표현식에 의해 호출됩니다. 아무런 동작도 수행하지 않습니다.
15-30) 사용자 정의 할당 해제 함수가 delete , delete [ ] 및 배치 new 표현식에 의해 호출됩니다.
27-30) 정의된 경우, delete 표현식은 * ptr 에 대한 소멸자를 실행하지 않고 operator delete 호출을 수행합니다. 대신, ptr - > ~T ( ) ; 와 같은 소멸자의 직접 호출이 이 operator delete 의 책임이 됩니다.

오버로드 ( 1-8 ) <new> 헤더가 포함되지 않더라도 각 번역 단위에서 암시적으로 선언됩니다.

오버로드 선택 기준은 delete expression 를 참조하십시오.

목차

매개변수

ptr - 할당 해제할 메모리 블록에 대한 포인터 또는 null 포인터
sz - 해당 할당 함수에 전달된 크기
place - 해당 placement new에서 placement 매개변수로 사용된 포인터
tag - non-throwing operator new가 사용한 태그와 일치하는 오버로드 구분 태그
al - 할당된 객체 또는 배열 요소의 정렬
args - placement 할당 함수와 일치하는 임의의 매개변수 ( std::size_t std::align_val_t 포함 가능)

예외

모든 할당 해제 함수는 noexcept ( true ) 선언에서 달리 명시되지 않는 한 예외를 발생시키지 않습니다.

(C++11부터)

할당 해제 함수가 예외를 던져서 종료되면, 그 동작은 정의되지 않습니다 , 심지어 그것이 noexcept ( false ) (C++11부터) 로 선언된 경우에도 마찬가지입니다.

전역 대체

오버로드 ( 1-12 ) 대체 가능 합니다. 기본 버전의 효과는 다음과 같습니다:

1) 만약 ptr 가 null이면, 아무 작업도 수행하지 않습니다. 그렇지 않으면, 이전에 operator new 호출로 할당된 저장 공간을 회수합니다.
2) operator delete ( ptr ) 를 호출하며, 마치 오버로드 (1) 가 이전 operator new [ ] 호출로 할당된 저장 공간을 회수할 수 있는 것처럼 동작합니다.
3) (1) 과 동일합니다.
4) 이전에 operator new [ ] 호출로 할당된 저장 공간을 회수할 수 있는 것처럼 오버로드 (3) operator delete ( ptr, al ) 를 호출합니다.
5) operator delete ( ptr ) 를 호출합니다.
6) operator delete [ ] ( ptr ) 를 호출합니다.
7) operator delete ( ptr, al ) 를 호출합니다.
8) operator delete [ ] ( ptr, al ) 를 호출합니다.
9) operator delete ( ptr ) 를 호출합니다.
10) operator delete [ ] ( ptr ) 를 호출합니다.
11) operator delete ( ptr, al ) 를 호출합니다.
12) operator delete [ ] ( ptr, al ) 를 호출합니다.

전역 operator new / delete 대체:

#include <cstdio>
#include <cstdlib>
#include <new>
// no inline, required by [replacement.functions]/3
void* operator new(std::size_t sz)
{
    std::printf("1) new(size_t), size = %zu\n", sz);
    if (sz == 0)
        ++sz; // avoid std::malloc(0) which may return nullptr on success
    if (void *ptr = std::malloc(sz))
        return ptr;
    throw std::bad_alloc{}; // required by [new.delete.single]/3
}
// no inline, required by [replacement.functions]/3
void* operator new[](std::size_t sz)
{
    std::printf("2) new[](size_t), size = %zu\n", sz);
    if (sz == 0)
        ++sz; // avoid std::malloc(0) which may return nullptr on success
    if (void *ptr = std::malloc(sz))
        return ptr;
    throw std::bad_alloc{}; // required by [new.delete.single]/3
}
void operator delete(void* ptr) noexcept
{
    std::puts("3) delete(void*)");
    std::free(ptr);
}
void operator delete(void* ptr, std::size_t size) noexcept
{
    std::printf("4) delete(void*, size_t), size = %zu\n", size);
    std::free(ptr);
}
void operator delete[](void* ptr) noexcept
{
    std::puts("5) delete[](void* ptr)");
    std::free(ptr);
}
void operator delete[](void* ptr, std::size_t size) noexcept
{
    std::printf("6) delete[](void*, size_t), size = %zu\n", size);
    std::free(ptr);
}
int main()
{
    int* p1 = new int;
    delete p1;
    int* p2 = new int[10]; // guaranteed to call the replacement in C++11
    delete[] p2;
}

가능한 출력:

// Compiled with GCC-5 in C++17 mode to obtain the following:
1) op new(size_t), size = 4
4) op delete(void*, size_t), size = 4
2) op new[](size_t), size = 40
5) op delete[](void* ptr)

operator delete operator delete [ ] 의 추가 사용자 정의 매개변수를 가진 오버로드("placement forms", ( 15,16 ) )는 일반적으로 전역 범위에서 선언될 수 있으며, 할당 중인 객체의 생성자가 예외를 발생시킬 경우 해당 placement 형태의 new 표현식에 의해 호출됩니다.

표준 라이브러리의 배치 형태 operator delete operator delete [ ] ( 13,14 ) 는 대체할 수 없으며, 배치 new 표현식이 :: new 구문을 사용하지 않은 경우에만 일치하는 서명을 가진 클래스별 배치 delete ( 25,26 ) 를 제공함으로써 사용자 정의할 수 있습니다: void T :: operator delete ( void * , void * ) 또는 void T :: operator delete [ ] ( void * , void * ) .

클래스별 오버로드

할당 해제 함수 ( 17-24 ) 는 클래스의 정적 멤버 함수로 정의될 수 있습니다. 이러한 할당 해제 함수는, 제공되는 경우, 이 클래스의 객체 ( 17,19,21 ) 와 배열 ( 18,20,22 ) 를 삭제할 때 delete 표현식에 의해 호출됩니다. 단, 클래스 범위 조회를 우회하는 :: delete 형식을 사용한 delete 표현식은 제외됩니다. 키워드 static 은 이러한 함수 선언에서 선택사항입니다: 키워드 사용 여부와 관계없이, 할당 해제 함수는 항상 정적 멤버 함수입니다.

delete 표현식은 클래스 범위부터 적절한 할당 해제 함수의 이름을 찾기 시작하며(배열 형태는 배열 요소 클래스의 범위에서 찾음), 일반적으로와 같이 멤버를 찾지 못할 경우 전역 범위로 진행합니다. 이름 검색 규칙 에 따라, 클래스 범위에서 선언된 모든 할당 해제 함수는 전역 할당 해제 함수들을 숨긴다는 점에 유의하세요.

삭제되는 객체의 정적 타입이 동적 타입과 다른 경우(예: 다형성 객체 를 기본 클래스 포인터를 통해 삭제할 때), 그리고 정적 타입의 소멸자가 가상인 경우, delete의 단일 객체 형식은 해당 가상 소멸자의 최종 오버라이더 정의 지점부터 할당 해제 함수 이름의 조회를 시작합니다. 런타임에 어떤 할당 해제 함수가 실행되든 관계없이, 컴파일을 위해 정적으로 보이는 operator delete 버전이 접근 가능해야 합니다. 다른 경우들, 즉 기본 클래스 포인터를 통해 배열을 삭제할 때, 또는 비가상 소멸자를 가진 기본 클래스 포인터를 통해 삭제할 때의 동작은 정의되지 않습니다.

단일 인자 오버로드 ( 17,18 ) 가 제공되지 않지만, 두 번째 매개변수로 std::size_t 를 취하는 크기 인식 오버로드 ( 21,22 ) 가 제공되는 경우, 일반 할당 해제 시 크기 인식 형태가 호출되며 C++ 런타임은 할당 해제될 객체의 크기를 두 번째 인자로 전달합니다. 두 형태가 모두 정의된 경우 크기 비인식 버전이 호출됩니다.

#include <cstddef>
#include <iostream>
// 크기 지정 클래스별 할당 해제 함수
struct X
{
    static void operator delete(void* ptr, std::size_t sz)
    {
        std::cout << "custom delete for size " << sz << '\n';
        ::operator delete(ptr);
    }
    static void operator delete[](void* ptr, std::size_t sz)
    {
        std::cout << "custom delete for size " << sz << '\n';
        ::operator delete[](ptr);
    }
};
int main()
{
    X* p1 = new X;
    delete p1;
    X* p2 = new X[10];
    delete[] p2;
}

가능한 출력:

custom delete for size 1
custom delete for size 18

operator delete operator delete [ ] 의 추가 사용자 정의 매개변수를 가진 오버로드("placement forms", ( 25,26 ) )도 클래스 멤버로 정의될 수 있습니다. 실패한 placement new 표현식이 호출할 해당 placement delete 함수를 찾을 때, 전역 범위를 검사하기 전에 클래스 범위에서 조회를 시작하며, placement new 와 시그니처가 일치하는 함수를 찾습니다:

#include <cstddef>
#include <iostream>
#include <stdexcept>
struct X
{
    X() { throw std::runtime_error("X(): std::runtime_error"); }
    // custom placement new
    static void* operator new(std::size_t sz, bool b)
    {
        std::cout << "custom placement new called, b = " << b << '\n';
        return ::operator new(sz);
    }
    // custom placement delete
    static void operator delete(void* ptr, bool b)
    {
        std::cout << "custom placement delete called, b = " << b << '\n';
        ::operator delete(ptr);
    }
};
int main()
{
    try
    {
        [[maybe_unused]] X* p1 = new (true) X;
    }
    catch (const std::exception& ex)
    {
        std::cout << ex.what() << '\n';
    }
}

출력:

custom placement new called, b = 1
custom placement delete called, b = 1
X(): std::runtime_error

클래스 수준의 operator delete 가 템플릿 함수인 경우, 반환 타입은 void , 첫 번째 인자는 void * 이어야 하며, 두 개 이상의 매개변수를 가져야 합니다. 즉, 배치 형태만 템플릿으로 작성할 수 있습니다. 템플릿 인스턴스는 그 시그니처와 관계없이 일반 할당 해제 함수가 될 수 없습니다. 템플릿 operator delete의 특수화는 템플릿 인자 추론 을 통해 선택됩니다.

참고 사항

다형성 클래스에서 클래스별 T :: operator delete 호출은 정적 멤버 함수가 동적 디스패치를 통해 호출되는 유일한 경우입니다.

다음 함수들은 스레드 안전성을 요구합니다:

특정 저장 단위를 할당하거나 해제하는 이러한 함수들의 호출은 단일 전체 순서로 발생하며, 각 해제 호출은 이 순서에서 다음 할당(있는 경우)에 대해 happens-before 관계를 가집니다.

(C++11부터)
기능 테스트 매크로 표준 기능
__cpp_sized_deallocation 201309L (C++14) 크기 지정 할당 해제
__cpp_impl_destroying_delete 201806L (C++20) 소멸 삭제 연산자 (컴파일러 지원)
__cpp_lib_destroying_delete 201806L (C++20) 소멸 삭제 연산자 (라이브러리 지원)

결함 보고서

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

DR 적용 대상 게시된 동작 올바른 동작
CWG 220 C++98 사용자 정의 해제 함수가 예외를 던지는 것이 허용됨 해제 함수에서 예외를 던지면
정의되지 않은 동작이 발생함
CWG 1438 C++98 유효하지 않은 포인터 값의 모든 사용이 정의되지 않은 동작이었음 간접 참조와 해제만 정의되지 않은 동작임
LWG 206 C++98 ( 2 ) 를 대체해도 ( 10 ) 의 기본 동작에 영향을 주지 않음 기본 동작이
그에 따라 변경됨
LWG 298 C++98 ( 1 ) 를 대체해도 ( 9 ) 의 기본 동작에 영향을 주지 않음 기본 동작이
그에 따라 변경됨
LWG 404 C++98 대체 가능한 해제 함수의 대체 함수를
inline 으로 선언할 수 있었음
금지되며, 진단이 요구되지 않음
LWG 2458 C++14 ( void * , std:: size_t , const
std:: nothrow_t & ) 를 취하는 오버로드가 명시되었지만 호출될 수 없었음
잘못된 오버로드가 제거됨

참고 항목

[static] (C++23)
operator new 에서 이전에 얻은 메모리를 할당 해제함
( std::generator<Ref,V,Allocator>::promise_type 의 public static member function)
할당 함수들
(function)
(C++17에서 사용 중단됨) (C++20에서 제거됨)
초기화되지 않은 저장 공간을 해제함
(function template)
이전에 할당된 메모리를 할당 해제함
(function)