재귀함수가 스택 메모리를 사용한다는 글을 보고, 정확한 메모리 구조를 알아보기 위해 작성했습니다.
프로세스 메모리
프로세스 메모리(Process Memory) 구조는 OS가 프로그램을 실행하기 위해 메모리(RAM)에 할당하는 구조를 뜻합니다. OS는 효율적인 메모리 관리를 위해서 프로세스 실행시 코드, 데이터, 힙, 스택 4가지 영역으로 나눠서 관리합니다.
메모리는 기본적으로 낮은 주소(Low Address)에서 높은 주소(High Address) 순서로 배치됩니다.
영역별 설명
코드 영역 (Code Segment)
작성된 소스코드가 기계어로 저장되는 영역이라서 코드(Code) 영역입니다. 프로그래머가 작성한 함수, 제어문, 상수 등 실행 가능한 기계어(Binary) 코드가 저장됩니다. 그래서 코드 영역을 텍스트 영역이라고 부르기도 합니다.
코드 영역은 실행 도중 코드가 변조되면 안되기 때문에 Read-Only로 읽기만 가능합니다. 컴파일 시점에 메모리의 크기가 결정됩니다.
CPU는 코드 영역에 저장된 명령을 가져가서 처리합니다.
데이터 영역 (Data Segment)
프로그램이 끝날 때까지 살아있는 전역 변수(Global Variable), 정적 변수(Static Variable)이 저장되는 영역입니다. 프로그램이 시작될 때 할당되고, 프로그램이 종료되면 소멸합니다.
힙 영역 (Heap Segment)
프로그래머가 직접 관리하는 메모리 공간입니다. 프로그래머가 필요할 때 할당하고 해제하는 동적 메모리 공간입니다.
프로그래머가 직접적으로 관리하기 때문에, 런타임시 크기가 결정됩니다. 힙 영역에 메모리를 할당 후 제대로 해제하지 않으면 메모리 누수(Memory Leak)이 발생합니다. 만약 Heap 영역이 계속해서 할당되다가 영역을 다 차지하게 되면 Heap Overflow가 발생합니다.
스택에 비해 상대적으로 접근 속도가 느립니다.
스택 영역 (Stack Segment)
함수 호출과 관련된 임시 데이터 저장 영역입니다. 함수 호출시 생성되는 지역 변수(Local Variable), 매개 변수 (Parameter), 리턴 주소(Return Address)가 저장되고, 함수가 종료되면 사라집니다.
스택 영역은 이름처럼 LIFO(Last In First Out, 후입선출) 형태로 동작합니다. 그래서 다른 메모리 영역과 다르게 높은 메모리 주소에 낮은 메모리 주소로 할당됩니다.
스택 영역은 컴파일 시점에 대략적인 크기가 결정되거나, OS 설정상 한계가 존재합니다. 만약 한계를 넘으면 Stack Overflow 에러가 발생합니다.
메모리 할당 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>
#define A 10 // Code 영역
int b = 20; // Data 영역
int c; // Data 영역
void test(int param) { // Stack 영역 - 매개변수
int d = 30; // Stack 영역 - 지역변수
// Heap 영역 - malloc (동적할당)
// Stack 영역 - 포인터 변수 e (지역변수)
int *e = (int*)malloc(sizeof(int));
// Heap 영역 할당 해제
free(e);
}
int main() {
test(5);
return 0;
}
