2008.10.11 05:33 책 정리/Exceptional C++

사실 난 이게 난이도 6이라는게 이해가 되지 않는다. 왜냐하면 new 연산자는 컴파일러에 의해서 한가지 단계가 감춰졌을 뿐더러, 쫒아 가기 힘든 구조라, 추론하기도 어렵다. 즉, 일개 프로그래머가 파악하기 힘든 구조이기 때문이다.(... 내가 멍청한 것 일 수도..)

이번 메모리 관리 부분은 그 유명한 Effective C++ 3판 항목 49 ~ 항목 52와 연계해서 보면, 몇가지는 추론을 통해 알 수 있을 것이다. 그렇다면 어떤 문제가 있는지 알아보고, 생각을 해보자.(생각 자체를 할 수 없다면 바로 분석으로 넘어가는게 좋다. 워낙에 정보가 없는 .. 연산자 이니..)

1.


이 코드의 클래스 B는 delete 들의 매개변수가 두개이고 class D는 매개변수가 한개다. 왜 이럴까? 또한 함수 선언들을 개선 할 방법은 무엇이 있을까?

 

2.


이 코드에서, 각 delete 표현에 어떠한 이유로 어느 operator delete()가 호출될까? 그리고 호출할 떄의 매개변수는 어떻게 전달 되어야 할까?

3.


이 코드는 합법적인 할당인가?

4.


이 코드에서 어떤 메모리 관련 오류들이나 문제들이 있을까?

 

 

분석


  이 코드에서 B는 두타입의 매개변수를 받고, D는 한타입의 매개변수를 받는 operator delete가 정의 되어 있다. 사람 취향이므로, 왜 다른지에 대해서 신경쓰지 말자. (왜냐하면 operator new 에는 3종류가 있고, 그 중 위치 지정 operator 에 대응되는 operator delete 가 두개 이상의 매개변수를 갖게 된다.)

이 코드에서 operator new 혹은 operator new[] 사용시 예외가 발생 되면 문제라고 하지만, 이해하지 못하겠다. 어디에 문제가 있을지 모르기 때문에 한번 정리해 보고, 생각을 정리해 둔다.

  1. D가 B의 이름을 가리는 문제, 하지만 B의 소멸자가 가상 소멸자이기 때문에 D를 참조하는 B형 레퍼런스라 할지라도, 정상적으로 B의 operator delete가 호출 되므로 예외가 발생해도 operator delete가 호출 된다.
  2. D 또는 B의 예외 발생시, 런타임 시스템에 의해서 D 또는 B의 operator delete or operator delete[]가 호출 되지 않을 것이다. 테스트 결과 클래스 전용 operator delete 들은 정상적으로 호출 되어 졌다.
  3. 기본 타입의 operator new 로 할당 하였을 경우, 본래의 객체 크기보다 더 큰 메모리를 할당 할 수 있다. 이때 예외가 발생하면, 메모리를 해체 하지 못하게 될 수 있는 문제, 아마도 이 문제 갔다.(테스트를 못해 봤기 때문에, 추측...) 이유는 operator delete에서 기본 타입 operator new로 얼만큼의 객체 크기를 할당 받았는지 operator delete에서 확인 할 길이 없기 때문이다.


  이 코드를 보면 문제로 의심되는 부분을 짚어 보자. delete pb1 호출시 operator delete가 virtual(operator new 와 delete는 virtual 이 되지 않는다)이 안되어 있어, 호출 되지 않을 것이라고 생각 되지만, 테스트 결과 B의 소멸자가 가상 소멸자이기 때문에 B의 operator delete가 참조형 delete flag 변수(무엇인지는 잘 모름 책에서는 이렇게 설명 되어 있다.) On 시켜서, D의 operator delete를 호출하여 정상적으로 객체 파괴가 되는 것을 볼 수 있다.


  이 코드는 바로 위의 코드와 다르게 배열을 참조하는 포인터를 해제하는 delete 를 호출 한다. 하지만 이것은 정상적으로 호출 되어 지지 않는 다고 허브 셔터는 말하고 있다. D의 operator delete[]에 배열의 크기를 전달 할 수 없기 때문이라고 한다.(effective C++ 2판에 보면 메모리 할당에 대한 자세한 이야기가 나오며, 배열의 메모리 할당에 대해서 보는게 좋을 듯 싶다.)



이 코드의 p1은 정상적으로 할당 되어 진다. 왜냐하면 f 는 B의 멤버 함수이고 PFM 는 클래스의 멤버를 받는 포인터 형이기 때문이다. 하지만 operator delete .. 되지 않는다 왜냐하면 operator delete 는 정적함수로 되기 때문이다.

그렇기 때문에, operator new or operator delete의 경우 앞에 static을 명시적으로 써주는것이 보다 더 좋은 습관이다. (안써줘도 정적 함수겠지만 상속자 혹은 프로그래머가 딱 보고 알수 있는게 제일 좋기 떄문이다.)


4번 문제는 좀 길어서 쓰기가 약간 힘들어 진다.^^; 이만 마치고 책을 보는게 좋을 듯 또는 1,2,3 의 해설을 보고, 4의 문제를 추론 할 수 있을 것이다..


총평
operator new 혹은 operator delete를 사용할 일이 거의 없기 때문에, 다소 생소한 문제들이였다. 여러가지 규칙들은 effective C++ 3판 2판에서 확인 할 수 있었고, 몇가지는 이해되고 몇가지는 이해가 되지 않았다. .. 다시 한번 볼 기회가 생기면, 그때로 미루어도 될 것이라 생각되고 지금까지 이해된 것들을 정리해 둔다.
posted by 농사를 짓는 게임 프로그래머 최익필

댓글을 달아 주세요