업데이트:

태그: ,

카테고리:



1. 자동저장기간 객체의 생성자가 exception을 던진다면

  • 자동저장기간 객체는 생성자가 exception을 throw하면 throw하기전에 destructor를 호출해 메모리를 해제한다.

pam이라는 객체의 생성자가 호출되고, 2번째 increasing grade에서 exception을 던진다.
그리고 이렇게 던져진 exception이 객체를 생성한 함수의 catch블럭에 들어오기 전에 try블럭이 소멸되면서 destructor가 먼저 호출되는 것을 볼 수 있다.



동적저장기간 객체가 생성시 exception이 발생하면 heap을 해제하는 것을 보장한다.

동적저장기간 객체는 2가지의 프로세스를 거치는데,

  1. 임시 포인터에 객체를 malloc해 공간을 만든다.

  2. 생성자를 호출해 메모리에 객체를 생성한다. 이때, 1번의 임시포인터가 this로 전달된다.

  • 위 2가지 프로세스가 try ~ catch블록으로 되어있어서 생성자가 exception을 던지면 catch블록에서 메모리공간을 해제한다.

  • 그리고 생성자가 던진 exception을 다시 던지게된다.

위의 프로세스는 기능적으로 아래 코드와 유사하다.

Fred* p;
void* tmp = operator new(sizeof(Fred)); //heap allocation
try {
  new(tmp) Fred();  // Placement new
  p = (Fred*)tmp;   // The pointer is assigned only if the constructor succeeds
}
catch (...) {
  operator delete(tmp);  // Deallocate the memory
  throw;                 // Re-throw the exception
}
  • 여기서 보이는 operator new와 operator delete는 C의 malloc과 free에 대응된다.



가령, 이런 코드가 있다고 생각해보자.

class A
{
	private:
		int *n;
	public:
		A(void) throw (std::exception)
		{
			cout<<"construct"<<endl;
			throw (std::exception());
			n = new int[5];
		}
		~A(void)
		{
			cout<<"deleting"<<endl;
			delete []n;
		}
};


int main(void)
{
	try {
		new A();
	} catch (std::exception &e)
	{
		cout<<e.what()<<endl;
	}
	while (1)
		;
	return 0;
}
  • 생성자가 호출되면서 바로 exception을 throw한다.
  • try 블럭에서 new로 할당된 공간은 A를 위한 공간 뿐이다.
  • 명시적으로 A가 동적할당이 해제되지는 않았지만, 이 코드에서 new A()는 leak을 발생시키지 않는다.
  • 그 이유는 위에서와 같이 operator new로 할당된 A의 공간이 내부적으로 operator delete가 호출되면서 해제되기 때문이다.

  • REF

댓글남기기