사실 난 이게 난이도 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[] 사용시 예외가 발생 되면 문제라고 하지만, 이해하지 못하겠다. 어디에 문제가 있을지 모르기 때문에 한번 정리해 보고, 생각을 정리해 둔다.
- D가 B의 이름을 가리는 문제, 하지만 B의 소멸자가 가상 소멸자이기 때문에 D를 참조하는 B형 레퍼런스라 할지라도, 정상적으로 B의 operator delete가 호출 되므로 예외가 발생해도 operator delete가 호출 된다.
- D 또는 B의 예외 발생시, 런타임 시스템에 의해서 D 또는 B의 operator delete or operator delete[]가 호출 되지 않을 것이다. 테스트 결과 클래스 전용 operator delete 들은 정상적으로 호출 되어 졌다.
- 기본 타입의 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판에서 확인 할 수 있었고, 몇가지는 이해되고 몇가지는 이해가 되지 않았다. .. 다시 한번 볼 기회가 생기면, 그때로 미루어도 될 것이라 생각되고 지금까지 이해된 것들을 정리해 둔다.
'책 정리 > Exceptional C++' 카테고리의 다른 글
항목 34 : 이름 검색과 인터페이스 - 파트 4 (난이도 9) (0) | 2008.10.16 |
---|---|
항목 33 : 이름 검색과 인터페이스 - 파트 3 (난이도 5) (0) | 2008.10.16 |
항목 32 : 이름 검색과 인터페이스 - 파트 2 (난이도 9) (0) | 2008.10.15 |
항목 31 : 이름 검색과 인터페이스 - 파트 1 (난이도 : 9½) (0) | 2008.10.15 |
항목 25 : 개체지향 프로그래밍 (난이도 4) (2) | 2008.10.14 |
항목 37 : AUTO_PTR (난이도 8) (0) | 2008.10.10 |
항목 35 : 메모리 관리 - 파트 1 (난이도 3) (0) | 2008.10.08 |
항목 41 : 개체 활동 주기 - 파트 2 (난이도 : 6) (0) | 2008.10.08 |
항목 40 : 개체 활동 주기 - 파트 1 (난이도 : 5) (0) | 2008.10.08 |
항목 39 : 자동 변환 (난이도 : 4) (0) | 2008.10.08 |
최근댓글