출처 : http://d.mumbi.net/cpp:new
정의
- operator new() 를 호출하여 메모리를 할당하고, 생성자를 호출한다.
- 힙( heap )메모리에 할당된다.
일반 변수
- new 연산자를 사용해 메모리를 할당한다. 모두 사용한 후 delete 연산자로 해제해 주어야 메모리 누수( leak )가 생기지 않는다.
- 메모리 할당에 실패시, std::bad_alloc 예외를 던진다. 단, nothrow new 는 0 을 반환한다.
int main( void ) { int* p = new int; // 할당 delete p; // 해제 }
배열
- new[] 연산자를 사용해 메모리를 할당한다. 모두 사용한 후 delete[] 연산자로 해제해 주어야 메모리 누수가 생기지 않는다.
- new[] 연산자로 할당한 메모리를 delete 연산자로 해제할 경우, 동작이 미정의( undefined )되어 있다.
- 다차원 배열도 delete[] 연산자로 해제해주면 된다.
1차원 동적 배열
int main( void ) { int n = 10; int* p = new int[n]; // 배열 할당 delete[] p; // 배열 해제 }
2차원 동적 배열
int main( void ) { int ( *p )[2] = new int[2][2]; // 배열 할당 delete[] p; // 배열 해제 }
메모리 지정 new( placement new )
- 이미 할당된 객체의 메모리에 해당 객체의 생성자를 호출하여 초기화 객체로 만든다.
- 기존의 메모리를 사용하므로 재할당은 하지 않고 생성자만 호출한다.
- 직접 메모리를 할당하지 않았기 때문에 delete 연산자로 해제하지 않는다.
/* operator new() 가 다음과 같이 재정의되어 있다. void* operator new( size_t, void* p ) { return p; } */ class Point { int x, y; public: Point( int a = 0, int b = 0 ) : x( a ), y( b ) { } }; int main( void ) { Point p( 1, 2 ); new( &p ) Point( 3, 4 ); // 메모리 지정 new }
nothrow new
- nothrow new 는 메모리 할당에 실패할 경우, 예외를 던지지 않고 0을 반환한다.
- 예전 new 는 0을 반환했기 때문에 예전 new 의 오류 검사 코드를 사용하기 위해 #define new new( nothrow ) 로 치환한다.
/* struct nothrow_t { }; nothrow_t nothrow; // cout << sizeof( nothrow_t ) << endl; // 사이즈는 1. void* operator new( size_t sz, const std::nothrow_t& ) // 실패시, 0 반환 { return malloc( sz ); } */ // 예전의 코드를 최신의 컴파일러에서 컴파일할 때 사용하는 방법. // #define new new( nothrow ) int main( void ) { int* p = new( nothrow ) int; if( 0 == p ) { // 실패 처리 } delete p; }
new_handler set_new_handler( new_handler )
- 메모리 할당을 위한 메모리가 부족할 때, 문제를 처리할 함수를 지정하는 함수이다.
- 새로운 핸들러를 저장하고, 기존의 핸들러를 반환한다.
new_handler
- new_handler 는 void( *new_handler )() 의 함수 포인터이다.
- 메모리 부족 시, new_handler 가 호출되는데, new_handler 는 다음 중 하나를 수행해야 한다.
- 메모리 부족 문제를 해결해야 한다.
- 프로그램을 종료하거나, 예외를 던져야 한다.
표준 new 의 구현
- 표준 new 가 어떻게 구현되었는지 정확히는 알 수 없으나, 다음과 같을 것이다.
void* operator new( std::size_t size ) throw( std::bad_alloc ) { if( 0 == size ) // new int[0]; 도 할당된다. size = 1; while( 1 ) { void* p = malloc( size ); // 메모리 할당 시도 if( 0 != p ) return p; new_handler handler = set_new_handler( 0 ); // 새로운 핸들러를 지정하면 기존 핸들러를 반환한다. set_new_handler( handler ); // 기존 핸들러를 얻기 위해 다른 핸들러를 지정했으니, 다시 핸들러를 지정한다. if( 0 != handler ) handler(); else throw std::bad_alloc(); } }
반응형
'C, C++' 카테고리의 다른 글
[C, C++] Formatting std::string (0) | 2014.03.03 |
---|---|
How to output long long or int64? (2) | 2014.03.03 |
[C++][STL] string documentation. (0) | 2014.01.15 |
[Windows32 API] Dialog 박스와 CreateWindow 같이 쓸 때 (0) | 2013.05.13 |
[C, C++][Windows] 윈도우 종료시 콜스택 [KernelBase.dll 에 첫째 예외가 있습니다] (0) | 2013.05.09 |
[C, C++][스크랩] #pragma warning (0) | 2013.04.18 |
[C++] 64비트 환경과 INT_PTR, int (0) | 2013.02.09 |
[C++] (Exception) std::bad_alloc (0) | 2013.02.07 |
가상함수가 있는 클래스의 이해와 멤버변수의 일괄 초기화 기법 (0) | 2013.01.13 |
C에서 malloc 과 C++에서 new 에 대한 고찰 (0) | 2012.10.22 |