## 어디에 있는 어떤 메모리의 구조인가
명령어의 집합일 뿐인 프로그램이 실행되면 OS는 프로그램 실행에 필요한 메모리를 할당해준다. 우리가 흔히 말하는 code-data-stack-heap으로 구분되는 메모리의 구조는 이렇게 프로그램에 할당되는 메모리의 구조를 의미한다.
OS가 실행 될 프로그램에게 할당해주는 메모리는 주로 RAM의 공간이다. 임베디드 환경의 경우에는 ROM에 code 영역과 data 영역의 일부가 할당되는데, 여기서는 일반적인 pc와 서버 환경만을 다룬다.
## 메모리의 구조
운영체제가 [[프로세스]]에 할당한 메모리 구조는 아래와 같다.
![[604e636f-aae3-405f-8e8e-c8fe36755a74.png]]
### 코드 영역
코드 영역은 사용자가 작성한 코드가 저장되는 영역이다. 함수 본문 상수로 지정된 문자열 리터럴을 포함한 컴파일된 기계어 코드가 저장되어 있다. 프로그램 실행 시에 읽기 전용으로 로드되기 때문에 수정이 불가능하다. (수정을 시도하면 세그멘테이션 폴트 에러가 난다.)
여러 프로세스가 같은 실행 파일을 실행하는 경우 OS는 이 영역을 공유해서 메모리를 절약하기도 한다.
PC에서는 보통 실행 파일이 디스크에 있다가 RAM으로 복사되어 실행되기 때문에 코드 영역이 RAM에 존재하는데, 임베디드 환경에서는 코드가 ROM에 저장되어 ROM에서 직접 실행되기도 한다.
### 데이터 영역
데이터 영역에는 초기 값이 있는 전역 변수나 static 변수가 저장된다.
```c
int count = 3; // 전역 변수
static double pi = 3.14 // static 변수
```
프로그램 시작 시에 실행 파일의 .data 섹션에 저장된 초기값이 RAM에 복사된다. 읽기와 쓰기가 모두 가능하고 프로그램 종료 시까지 유지된다.
PC에서는 데이터 영역 또한 RAM에 저장되는데, 임베디드 환경에서는 데이터 영역의 초기값들은 ROM에 저장되고, 부팅 시에 RAM에 복사된다는 차이점이 있다.
### BSS 영역
BSS 영역에는 초기화되지 않은 전역 변수들과 static 변수들이 저장된다.
```c
int count; // 초기화되지 않은 전역 변수
static int value; // 초기화되지 않은 static 변수
```
따로 저장하는 이유는 메모리 사용 효율과 실행 파일 크기 절감 때문이다. 초기값이 주어진 data 영역에 들어가는 변수들은 변수마다 값을 넣어서 저장해야 한다. 하지만 초기값이 주어지지 않은 bss 영역의 변수들은 값을 지정할 필요 없이 그냥 변수가 있다는 것만 저장하면 된다. 실행 파일에는 값 자체를 저장하지 않고 필요한 크기만 기록하기 때문에 파일 크기를 절감할 수 있는 것이다.
참고: [.bss - Wikipedia](https://en.wikipedia.org/wiki/.bss)
### 스택 영역
스택에는 함수 호출 시 생성되는 스택 프레임이 저장된다. 스택 프레임에는 함수 내의 지역 변수와 함수의 매개변수가 포함되어 있다.
LIFO 구조로 함수 호출 시에 할당되고, 종료 시에 메모리에서 해제된다. 크기가 가변적이긴 하지만 과도한 재귀 함수 호출 시에는 overflow가 발생할 수 있다. (Stack Overflow)
### 힙 영역
힙 영역에는 malloc, calloc, realloc 같은 함수들로 동적으로 할당한 데이터들이 저장된다. 동적으로 할당하는 것이기 때문에 런타임에 크기가 결정되고, 필요한 경우에는 확장하거나 축소할 수 있다.