메모리 공간의 이해
<레지스터, 스택, 힙, 데이터 영역>
1) 레지스터 (Register)
레지스터는 CPU나 프로그램이 접근할수 있는 메모리 영역중 가장 빨리 접근 할 수 있는 곳이라고 할 수 있다.
보통은 CPU의 경우 내부 메모리로 설정되어있으며 RAM 같은 외부 메모리와는 다르다.쉽게 생각해서 CPU안에 숨어있는 메모리라고 보면 되겠다. (우리가 흔히 보는 4GB DRAM 같은 것은 외부 메모리이다.)
보통의 CPU는 "로드스토어 구조"라는 레지스터 접근 방식을 택하는데, 이는 지금 당장 연산이 이루어지는 메인 메모리의 데이터를 레지스터로 가져온후 연산을 하고 이후 다시 메인메모리로 저장하는 구조이다. 보통 레지스터는 메모리 계층의 최상위에 위치한다고 한다.
C/C++언어를 작성할 때, 특히 for문 같은 문법을 사용할때는 for문의 인자를 레지스터 변수로 선언하면 연산속도를 증가시킬 수 있다.
예) register int i;
for(i=0;i
하지만 요즘의 컴파일러들은 위와같은 register 변수 선언을 굳이 하지 않아도 코드 최적화를 통해 위와같은 변수들은 레지스터로 보내는 경향이 있다.
2) 스택 (Stack)
스택은 LIFO (Last Input First Output)의 경향을 가지는 메모리 영역으로 영어 단어 그대로 차곡차곡 "쌓는"메모리영역이다.
데이터를 쌓기 때문에 처음 쌓인 데이터가 가장 늦게 출력된다.
C/C++ 프로그래밍에서는 지역변수(local variable)이 저장되는 영역이고, 대부분의 함수 내에서의 변수 선언은 모두 스택에 저장된다고 보면 된다. 또한 함수 호출이 완료되면 데이터도 사라진다. 따라서, 스택에서 선언되는 변수는 메모리 관리에 대해 신경쓸 필요가 없다. 호출이 완료되면 저절로 사라지기 때문에 메모리에 남아있지 않는다.
3) 힙(Heap)
힙은 전적으로 프로그래머가 관리하는 메모리 영역이다. 이 영역의 의미는 다음과 같이 생각할수 있다.
스택의 경우, 앞서 지역변수가 저장되는 영역이라고 했다. 따라서, 함수가 호출되는 경우 컴파일러는 함수 안에 선언되어있는 지역변수들의 자료형을 훑어본 후, 이 함수가 실행되기 위해 필요한 스택의 메모리 양을 찾아낸다. 이때 중요한 것이 컴파일러는 스택 메모리 양을 계산할때 선언된 지역변수의 초기값에는 관심이 없다 . 즉, 초기값과는 상관없이 몇 바이트의 자료형이 선언되어있는지만 확인한다. 그래야 스택 메모리 양을 계산할 수 있기떄문이다. 그렇다면, 스택 메모리를 쓸때 한가지 불편한 점이 있다.
사용자가 때에 따라 유동적으로 메모리를 할당해주고 싶을때 스택 영역을 사용하기 쉽지 않다.
즉, 메모리 할당을 변수를 사용하여 프로그래머가 유동적으로 하고 싶을때는 스택 영역의 메모리를 사용하기 어렵다. 이를 어려운 말로는 "컴파일-타임"이 아니라 "런-타임"에 메모리 할당을 한다고 한다. 즉, 프로그램이 실제로 실행할때 유동적으로 메모리 할당이 이루어진다는 뜻이다. 이때 바로 힙이 사용된다. 그리고, 힙에 메모리를 할당하는 것을 동적할당이라고 한다.
동적할당을 할때는 C의 경우는 malloc, calloc 명령어가, C++인 경우는 new 명령어가 사용된다. 또한 동적할당시 중요한 점이 할당된 메모리는 반드시 해제되어야 한다는 점이다. 이때 C에서는 free, C++에서는 delete 명령어가 사용된다.
4) 데이터 영역
데이터 영역은 전역변수(Global variable)나 static 변수가 저장되는 메모리 영역이다. 이 영역에 할당된 메모리는 프로그램 자체가 완전히 종료되어야 삭제된다. 따라서, 프로그램 실행 내내 접근되거나 update 되어야 하는 변수들은 데이터 영역에 할당하면 된다.
'Programming > C/C++' 카테고리의 다른 글
데이터(Data), 힙(Heap), 스택(Stack) 영역 (0) | 2012.06.27 |
---|---|
빅 엔디안(Big Endian) 과 리틀 엔디안(Little Endian) (0) | 2012.06.25 |
static const int vs const static int (0) | 2012.06.07 |
4장, 작은 객체에 대한 메모리 할당 - 1 : 메모리 풀은 무엇이며, 왜 필요한가? (3) | 2012.03.31 |
Convert char* to string (0) | 2012.01.19 |