C언어의 메모리 구조: 데이터(Data), 스택(Stack) 그리고 힙(Heap) 영역

우리가 프로그래밍 언어로 작성한 프로그램을 실행시키기 위해서는 메모리 공간이 필요하다. 효율적으로 메모리를 관리하고 활용하는 사람이 좋은 프로그래머라고 볼 수 있다. 똑같은 기능을 구현하는데 A라는 프로그래머는 1기가바이트를 사용했고, B라는 프로그래머는 10기가바이트를 사용했다면 당연히 A 프로그래머가 만든 프로그램을 사용하지 않겠는가? 


실행중인 프로그램은 운영체제로부터 메모리 공간을 할당 받는데, 할당되는 메모리 공간은 크게 데이터, 스택, 힙 영역으로 나눠진다. 



▶ 데이터, 스택, 힙 영역이란?


데이터 영역에는 전역 변수와 static 변수가 할당된다. 전역 변수는 메인 함수의 밖에 선언되는 변수로 프로그램 어디에서나 접근이 가능하며 한번 초기화하면 두 번 다시 초기화 할 수 없다는 특징이 있다. static 변수는 변수 선언시 앞에 static이라는 키워드를 붙여서 선언한 변수로 초기화하면 그 값을 나중에 바꿀 수 없는 변수이다. 전역 변수와 static 변수 모두 초기화하면 다시 초기화할 수 없다는 공통점이 있지만, static 변수는 전역 변수와 달리 선언된 지역 내에서만 접근이 가능하다. 


스택 영역에는 함수 호출 시 생성되는 지역 변수와 매개 변수가 저장된다. 지역 변수는 main 함수든 어떠한 형태의 함수든 함수의 몸체 부분에서 선언된 변수를 의미하고, 매개 변수는 함수의 선언부에 선언되는 변수들이다. 이 영역에 할당된 변수들은 함수 호출이 완료되면 사라진다는 특징이 있다. 


힙 영역은 프로그래머가 필요에 따라 메모리를 할당하거나 소멸할 때 사용되는 메모리 공간이다. C언어에서는 malloc 함수를 이용해서 힙 영역에 메모리를 할당할 수 있고, 그 할당된 메모리는 free 함수를 호출함으로 소멸할 수 있다. malloc과 free의 역할은 C++에서 new와 delete로 대체된다.  


메모리 구조를 그림1과 같이 간단히 나타낼 수 있다[1]. 


그림1. C언어의 메모리 관리 구조




▶ 데이터, 스택, 힙 영역에 메모리가 할당되고 소멸되는 방식을 보여주는 예제


간단한 예제를 통해 데이터 영역, 힙 영역, 스택 영역에 메모리가 할당되고 소멸되는지 확인해보자. 우선 코드는 그림1과 같다. 각 변수들 위에 어떤 변수인지 마킹해놓았다.  


그림2. 메모리의 흐름을 보여주기 위한 예제 코드


이 프로그램을 시작하면 우선 7, 8번째 행에서 전역변수 k와 h를 선언한다. 전역변수는 데이터 영역에 할당된다(그림3-1).  


그림3-1. 전역변수 k와 h가 데이터 영역에 할당된 모습


그 다음에는 main함수가 호출되고, 12행의 지역 변수 m이 스택 영역에 할당된다(그림3-2). 이때 데이터 영역에 할당된 전역변수들은 그대로 남아있다. 이것들은 프로그램이 종료될 때까지 메모리상에 존재하게 된다.



그림3-2. 지역 변수 m이 스택 영역에 할당된 모습


14행에 도달하면 fct1함수를 호출하면서 인자로 m이 전달된다. fct1함수의 매개 변수 a는 500으로 초기화되고, fct1함수 내에 선언되어 있는 지역 변수 aa도 1로 초기화된다. 매개변수 a와 지역 변수 aa모두 스택 영역에 할당된다(그림3-3). main 함수는 아직 호출이 완료된 상태가 아니기 때문에 main함수를 위한 스택 공간은 아직 그대로 존재한다.


그림3-3. fct1함수가 호출되면서 매개 변수 a와 지역변수 aa가 스택 영역에 할당된 모습.


다음 행으로 넘어가면, fct2함수가 호출되면서 인자로 m이 전달된다. 그 전에 fct1 함수는 호출이 완료되었기 때문에 fct1 함수를 위한 스택 공간은 소멸되고, 그 자리에 fct2 함수를 위한 공간이 할당된다. 마찬가지로 매개변수 b와 지역 변수 bb가 스택 영역에 할당된다(그림3-4). 


그림3-4. fct2의 매개변수 b와 지역변수 bb가 스택 영역에 할당된 모습.


15행을 지나가면 마찬가지로 fct2함수를 위한 스택 공간이 소멸된다. 그리고 힙 영역에 메모리를 할당해주기 위한 코드 17~20행을 지나고나면, 힙 영역에 변수 s가 할당된다(그림3-5).


그림3-5. malloc 함수를 사용해서 힙 영역에 메모리를 할당한 모습

  

22행에 이르면 free 함수로 인해 힙 영역에 할당되었던 변수 s를 위한 공간이 소멸된다. 그리고 main 함수가 종료되면서 main 함수에 할당되어 있던 스택 영역도 지워지고 처음에 데이터 영역에 할당된 전역 변수들을 위한 공간들도 지워진다(그림3-6). 


그림3-6. 프로그램 종료와 함께 할당되어 있던 메모리들이 모두 사라진다.



위 예제의 내용들을 엄밀히 따지면 조금 정확치 않은 부분들도 있겠지만, 이런 방식으로 메모리가 데이터 영역, 스택 영역, 힙 영역에 할당되고 소멸된다는 것을 알고 코딩한다면 훨씬 멋진 프로그램을 만들 수 있을 것이다. 




<참고 자료> 

[1] C 프로그래밍, 윤성우 지음, 프리렉, p. 571-592.

[2] 열혈 C++ 프로그래밍, 윤성우 지음, 오렌지미디어, p. 62-63. 

댓글()