operator delete 함수
new 연산자를 사용하여 동적으로 할당되는 메모리는 delete 연산자를 사용하여 비울 수 있습니다. delete 연산자는 operator delete 함수를 호출합니다. 이 함수는 메모리를 사용 가능한 풀로 다시 비웁니다. delete 연산자를 사용하면 클래스 소멸자(있을 경우)도 호출됩니다.
전역 및 클래스 범위의 operator delete 함수가 있습니다. 하나의 operator delete 함수만 특정 클래스에 대해 정의할 수 있으며, 정의하는 경우 전역 operator delete 함수가 숨겨집니다. 전역 operator delete 함수는 항상 모든 형식의 배열에 대해 호출됩니다.
전역 operator delete 함수는 선언되는 경우 할당 해제할 개체에 대한 포인터를 포함하는 void * 형식의 단일 인수를 사용합니다. 반환 형식은 void입니다(operator delete는 값을 반환할 수 없음). 클래스 멤버 operator delete 함수에는 두 가지 형태가 있습니다.
void operator delete( void * );
void operator delete( void *, size_t );
앞의 두 변형 형태 중 하나만 특정 클래스에 있을 수 있습니다. 첫 번째 형태는 전역 operator delete에 대해 설명한 대로 작동합니다. 두 번째 형태에는 두 개의 인수가 사용됩니다. 첫 번째 인수는 할당 해제할 메모리 블록에 대한 포인터이고 두 번째 인수는 할당 해제할 바이트 수입니다. 두 번째 형태는 기본 클래스의 operator delete 함수를 사용하여 파생 클래스의 개체를 삭제할 때 특히 유용합니다.
operator delete 함수는 정적입니다. 따라서 가상일 수 없습니다. operator delete 함수는 멤버 액세스 제어에 설명된 대로 액세스 제어를 따릅니다.
다음 예제에서는 메모리의 할당 및 할당 해제를 기록하기 위해 설계된 사용자 정의 operator new 및 operator delete 함수를 보여 줍니다.
예제
// spec1_the_operator_delete_function1.cpp
// compile with: /EHsc
// arguments: 3
#include <iostream>
using namespace std;
int fLogMemory = 0; // Perform logging (0=no; nonzero=yes)?
int cBlocksAllocated = 0; // Count of blocks allocated.
// User-defined operator new.
void *operator new( size_t stAllocateBlock ) {
static int fInOpNew = 0; // Guard flag.
if ( fLogMemory && !fInOpNew ) {
fInOpNew = 1;
clog << "Memory block " << ++cBlocksAllocated
<< " allocated for " << stAllocateBlock
<< " bytes\n";
fInOpNew = 0;
}
return malloc( stAllocateBlock );
}
// User-defined operator delete.
void operator delete( void *pvMem ) {
static int fInOpDelete = 0; // Guard flag.
if ( fLogMemory && !fInOpDelete ) {
fInOpDelete = 1;
clog << "Memory block " << cBlocksAllocated--
<< " deallocated\n";
fInOpDelete = 0;
}
free( pvMem );
}
int main( int argc, char *argv[] ) {
fLogMemory = 1; // Turn logging on
if( argc > 1 )
for( int i = 0; i < atoi( argv[1] ); ++i ) {
char *pMem = new char[10];
delete[] pMem;
}
fLogMemory = 0; // Turn logging off.
return cBlocksAllocated;
}
Visual C++ 5.0 이후부터 컴파일러는 클래스 선언에서 멤버 배열, new 및 delete 연산자를 지원합니다. 예를 들면 다음과 같습니다.
// spec1_the_operator_delete_function2.cpp
// compile with: /c
class X {
public:
void * operator new[] (size_t) {
return 0;
}
void operator delete[] (void*) {}
};
void f() {
X *pX = new X[5];
delete [] pX;
}
주석
앞의 코드를 사용하여 "메모리 누수"를 검색할 수 있습니다. 메모리 누수는 사용 가능한 저장소에 할당되었지만 비워지지 않은 메모리를 의미합니다. 이 검색 작업을 수행하기 위해 메모리의 할당 및 할당 해제 횟수를 셀 수 있도록 전역 new 및 delete 연산자가 다시 정의됩니다.