개요
지정한 메모리에 객체를 초기화
메모리 할당과 초기화를 분리하기 위한 기법
메모리 할당 시점에 타입을 정할 수 없거나 초기화 시점을 지정하고 싶은 경우에 사용
pool(connection, momory, …), 다형성 등
주의사항
placement new 사용 시 delete 대신 소멸자를 직접 호출하고 메모리 해제는 할당한 곳에서 할당 방법에 따른 적절한 해제를 해야함
delete의 경우 객체 소멸과 operator delete를 통한 메모리 해제 수행
placement new에서 할당한 메모리가 아니기 때문에 객체 소멸만 책임을 지는 것이 논리적
예제
코드
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std ;
class Base {
protected:
int i ;
public:
Base ( int i ) : i ( i ) { cout << "Base()" << endl ; }
virtual ~ Base () { cout << "~Base()" << endl ; }
virtual void Print () = 0 ;
};
class Derived_1 : public Base {
private:
char c ;
public:
Derived_1 ( int i , char c ) : Base ( i ), c ( c ) {
cout << "Derived_1()" << endl ;
}
virtual ~ Derived_1 () { cout << "~Derived_1()" << endl ; }
virtual void Print () override {
cout << this -> i << ", " << this -> c << endl ;
}
void Func1 () { cout << "Func1()" << endl ; };
};
class Derived_2 : public Base {
private:
string s ;
public:
Derived_2 ( int i , string s ) : Base ( i ), s ( s ) {
cout << "Derived_2()" << endl ;
}
virtual ~ Derived_2 () { cout << "~Derived_2()" << endl ; }
virtual void Print () override {
cout << this -> i << ", " << this -> s << endl ;
}
void Func2 () { cout << "Func2()" << endl ; };
};
void malloc_test () {
cout << "--- " << __func__ << " start ---" << endl ;
Base * base = static_cast < Base *> ( malloc ( sizeof ( Base ) * 1 ));
cout << "~~~" << endl ;
Derived_1 * derived = new ( base ) Derived_1 ( 1 , 'a' );
base -> Print ();
derived -> Print ();
static_cast < Derived_1 *> ( base ) -> Func1 ();
base ->~ Base ();
free ( base );
cout << "--- " << __func__ << " end ---" << endl ;
}
void calloc_test () {
cout << "--- " << __func__ << " start ---" << endl ;
Base * base = static_cast < Base *> ( calloc ( 1 , sizeof ( Base )));
cout << "~~~" << endl ;
Derived_1 * derived = new ( base ) Derived_1 ( 1 , 'b' );
base -> Print ();
derived -> Print ();
static_cast < Derived_1 *> ( base ) -> Func1 ();
base ->~ Base ();
free ( base );
cout << "--- " << __func__ << " end ---" << endl ;
}
void operator_new_test_1 () {
cout << "--- " << __func__ << " start ---" << endl ;
Base * base = static_cast < Base *> ( operator new ( sizeof ( Base )));
cout << "~~~" << endl ;
Derived_2 * derived = new ( base ) Derived_2 ( 1 , "aaa" );
base -> Print ();
derived -> Print ();
static_cast < Derived_2 *> ( base ) -> Func2 ();
base ->~ Base ();
operator delete ( base );
cout << "--- " << __func__ << " end ---" << endl ;
}
void operator_new_test_2 () {
cout << "--- " << __func__ << " start ---" << endl ;
const int size = 3 ;
unsigned char pool [ sizeof ( Derived_2 ) * size ];
for ( int i = 0 ; i < size ; ++ i ) {
new ( pool + ( sizeof ( Derived_2 ) * i )) Derived_2 ( i , "a" );
}
for ( int i = 0 ; i < size ; ++ i ) {
reinterpret_cast < Derived_2 *> ( pool + sizeof ( Derived_2 ) * i ) -> Print ();
}
for ( int i = 0 ; i < size ; ++ i ) {
reinterpret_cast < Derived_2 *> ( pool + sizeof ( Derived_2 ) * i )
->~ Derived_2 ();
}
cout << "--- " << __func__ << " end ---" << endl ;
}
int main () {
malloc_test ();
cout << endl ;
calloc_test ();
cout << endl ;
operator_new_test_1 ();
cout << endl ;
operator_new_test_2 ();
return 0 ;
}
실행 결과
--- malloc_test start ---
~~~
Base()
Derived_1()
1, a
1, a
Func1()
~Derived_1()
~Base()
--- malloc_test end ---
--- calloc_test start ---
~~~
Base()
Derived_1()
1, b
1, b
Func1()
~Derived_1()
~Base()
--- calloc_test end ---
--- operator_new_test_1 start ---
~~~
Base()
Derived_2()
1, aaa
1, aaa
Func2()
~Derived_2()
~Base()
--- operator_new_test_1 end ---
--- operator_new_test_2 start ---
Base()
Derived_2()
Base()
Derived_2()
Base()
Derived_2()
0, a
1, a
2, a
~Derived_2()
~Base()
~Derived_2()
~Base()
~Derived_2()
~Base()
--- operator_new_test_2 end ---
Tags:
C++ ,
C++98 ,
calloc ,
free ,
malloc ,
operator delete ,
operator new ,
placement new ,
programming-language
Categories:
C++ ,
programming-language
Updated: July 8, 2022