5. C/C++의 메모리 세그먼트(Memory Segment)
1. 변수 유형
- C/C++ 프로그램이 실행될 때마다 일부 메모리가 프로그램 실행을 위해 RAM에 할당된다.
- 이 메모리는 자주 실행되는 코드(이진 데이터), 프로그램 변수 등을 저장하는 데 사용된다.
- 일반적으로 다음과 같은 유형의 변수가 있다.
1] 로컬 변수(C에서는 자동 변수)
2] 글로벌 변수
3] 정적 변수
4] 글로벌 정적 또는 로컬 정적 변수를 가질 수 있지만 위의 세 가지가 상위 유형이다.
2. C/C++의 5가지 메모리 세그먼트
1) 코드(텍스트) 세그먼트
- 텍스트 세그먼트라고도 하는 코드 세그먼트는 자주 실행되는 코드를 포함하는 메모리 영역이다.
- 코드 세그먼트는 종종 버퍼 오버플로우 등과 같은 버그를 프로그래밍하여 오버라이드될 위험을 피하기 위해 읽기 전용이다.
- 코드 세그먼트에는 로컬 변수, 글로벌 변수 등과 같은 프로그램 변수가 포함되어 있지 않다.
- C/C++ 구현에 따라 코드 세그먼트에는 읽기 전용 문자열 리터럴도 포함될 수 있다.
- 예를 들어,
printf("Hello, world");
에서 문자열"Hello, world"
가 코드(텍스트) 세그먼트에 생성된다.
2) 초기화되지 않은 데이터 세그먼트
- 이 세그먼트는 BSS(Block Started by Symbol)라고도 한다.
- 이 세그먼트는 다음과 같은 유형의 변수를 포함한다.
1] 초기화되지 않은 글로벌 변수 (포인터 변수 포함)
2] 초기화되지 않은 상수 글로벌 변수
3] 초기화되지 않은 로컬 정적 변수
- 초기화되지 않은 글로벌 또는 정적 로컬 변수는 초기화되지 않은 데이터 세그먼트에 저장된다.
- 예를 들어, 글로벌 변수
int globalVar;
또는 정적 로컬 변수static int localStatic;
은 초기화되지 않은 데이터 세그먼트에 저장된다. - 글로벌 변수를 선언하고
0
또는NULL
로 초기화하더라도 여전히 초기화되지 않은 데이터 세그먼트 또는 BSS에 포함된다.
3) 초기화 된 데이터 세그먼트
- 이 세그먼트는 다음과 같은 유형의 변수를 포함한다.
1] 초기화된 글로벌 변수 (포인터 변수 포함)
2] 초기화된 상수 글로벌 변수
3] 초기화된 로컬 정적 변수
- 예를 들어, 글로벌 변수
int globalVar = 1;
또는 정적 로컬 변수static int localStatic = 1;
은 초기화된 데이터 세그먼트에 저장된다. - 이 세그먼트는 초기화된 읽기 전용 영역과 초기화된 읽기/쓰기 영역으로 더 분류될 수 있다.
- 초기화된 상수 글로벌 변수는 초기화된 읽기 전용 영역으로 이동하고, 런타임 시 값을 수정할 수 있는 변수는 초기화된 읽기/쓰기 영역으로 이동한다.
- 이 세그먼트의 크기는 프로그램 소스 코드의 값 크기에 따라 결정되며 런타임 시 변경되지 않는다.
4) 스택 세그먼트
- 스택 세그먼트는 사용자 정의 함수 또는 메인 함수 내부에서 생성되는 변수를 저장하는 데 사용되는 세그먼트이다.
- 이 세그먼트는 다음과 같은 유형의 변수를 포함한다.
1] 함수의 로컬 변수 (포인터 변수 포함)
2] 함수에 전달된 인수
3] 반환 주소(Return Address)
- 스택 세그먼트에 저장된 변수는 함수 실행이 완료되는 즉시 제거된다.
5) 힙 세그먼트
- 힙 세그먼트는 동적 메모리 할당을 지원하기 위한 세그먼트이다.
- C/C++에서 동적으로
malloc
,calloc
또는realloc
등을 사용하여 동적 메모리를 할당할 수 있다. - 예를 들어,
int *ptr = malloc(sizeof(int) * 2)
와 같이 8바이트가 힙 세그먼트에 할당되고 해당 위치의 메모리 주소가 반환되어 포인터 변수ptr
에 저장된다. - 이때 포인터 변수
ptr
은 사용/선언되는 방식에 따라 스택 세그먼트나 데이터 세그먼트에 포함될 수 있다.