삽질의 현장/- MFC

#003_MFC_메모리의 구성

shovelman 2015. 10. 16. 16:47


안녕하세요 삽잡이 입니다.


이번 시간에는 코드 영역과 데이터 영역에 대해서

메모리 구조에 대해서 MFC 관점으로 알아보겠습니다.



프로그램은 명령어와 데이터의 집합으로 이루어져 있습니다.
데이터를 input 받고 명령어를 통해 가공을하여 output 하는 식이죠...


MFC를 두고 예를 들어보도록 하겠습니다.

MFC 주요 클래스인 'CFrameWnd', 'CView', 'CDocument' 등은 
모두 동적 할당 을 통해 Heap 영역에 저장됩니다.

그리고 동적 할당을 통해 생성된 객체에서 사용하는 지역 변수들은 
Stack영역에 만들어지고요...

WM_LBUTTONDOWN과 같은 윈도우 메시지들은 코드영역에 자리를 잡습니다.
이 외에도 함수들 즉, 메소드들도 코드영역에 자리를 잡습니다.

예를 들어 View라는 클래스에 Sap() 이라는 메소드가 있다고 해봅시다.
만약, View의 객체에서 Sap() 메소드를 호출할 때 이 행동의 영향은 호출한 객체에게 갑니다. 
당연한 소리이지요...
그래서 이 Sap() 이라는 메소드를 인스턴스 메소드라고 부릅니다.

명령은 코드영역에 있습니다.
그런데 이 명령은 컴파일이 되면 변하지 않습니다.
우리가 배우는 언어들은 컴파일이 되면 변하지 않기 때문에 명령이 변하지 않지요...

만약 View() 라는 객체가 1000개가 만들어진다고 해봅시다.
그렇다면 Sap() 이라는 명령어가 1000개 만들어질까요?
아닙니다.
뭐 물론... 논리적으로는 각각의 객체가 Sap()이라는 함수를 가지고 있겠지만,
실제로는 Sap() 이라는 함수는 달랑 하나입니다.

그렇다면, Sap() 함수 호출 시 1000개의 객체 중 누가 Sap()함수를 호출했는지 알 수 있을까요?
사실, 호출 규약이라는 함수간의 호출 시 약속에 의해 
클래스 멤버 함수에서는 객체의 포인터(this)가 전달 됩니다.
참고로 클래스 멤버 함수간의 호출 규약은 thiscall 입니다.

따라서, 실제로는 컴파일러가
'Sap() 주소에 n번째 객체의 주소를 전달하라' 이렇게 호출을 한다 이겁니다...
그러면 자기 객체의 주소를 먼저 받는 함수로 규약이 되어있다 이겁니다.
그게 바로 this이구요...

만약 Sap() 이라는 메소드에 a, b 변수가 있다면
이는 this->x, this->y를 뜻하는 것이었습니다.

결과적으로 물리적으로는 메소드가 하나 만들어지는 것입니다.
메소드가 컴파일 후 변경되지 않기 때문에,
Code 영역의 명령어는 변하지 않기 때문에 가능한 일이지요...



함수 체계와 메모리 체계는 다릅니다.
명령어는 명령어일 뿐, 데이터는 데이터일 뿐입니다.

각각 Code 영역과 Data 영역으로 나뉘어져 있고
또 이 Data 영역은 Global 데이터 영역과 Stack, Heap 영역으로 나뉘어져 있지요...


논리적으로 Sap() 이라는 메소드는 View라는 객체의 것입니다.
따라서 Sap() 메소드를 사용할 때에는 해당 객체에 있는 메소드의 멤버 변수를 써야됩니다.
왜냐하면 객체가 많다고 해봅시다... 
한 메모리에 Sap()함수에 대한 결과 값을 보관하면 되겠습니까?

이런 측면에서라도 각 객체의 멤버 변수에 보관을 해야합니다.
따라서 Global Data 영역에 있는 전역 변수의 경우 객체 지향에서는 아예 쓰지 않습니다.
정말 가끔 사용하지요...

전역변수를 무작위로 사용하고 있다면 그 코드는 잘못된 방향으로 흘러가고 있는 것입니다.
만약, 프로그램 시작 시, 종류 후에 생성과 소멸을 반드시 하고 싶다면,
그때는 뭐 써야겠지요...
그리고 전역 변수가 필요할 때에는 클래스로 감싸 static 변수로 만들어주는 것이 좋습니다.
static 변수는 클래스의 인스턴스 없이 사용할 수 있죠...
물론 어디서든 접근 권한만 준다면 말입니다...


여기까지 알아보도록 하겠습니다.
이상 삽잡이였습니다!


'삽질의 현장 > - MFC' 카테고리의 다른 글

#006_MFC_Control, Value형 변수  (0) 2015.10.19
#005_MFC_Document Template 설명  (0) 2015.10.19
#004_MFC_동적 배열 CArray 설명  (0) 2015.10.19
#002_MFC_View (기본적인 입출력)  (0) 2015.10.15
#001_MFC_Intro  (0) 2015.10.15