1. 프로세스에서 할당하는 메모리 (4가지 영역)
: C/C++은 메모리를 직접 제어할 수 있는 언어이기 때문에, 프로세스 메모리 구조를 이해하는 것이 특히 중요하다.
1) 코드 영역 (Code / Text Segment)
- C/C++ 예시
: 소스 코드 자체, 컴파일된 함수들의 기계어 명령, 상수가 이곳에 저장된다.
- C/C++ 특징
: *프로그램이 실행되면 CPU가 이 영역의 명령어를 한 줄씩 읽어서 처리한다.
- 임의로 수정하려고 하면 세그멘테이션 폴트(Segmentation Fault) 같은 런타임 에러가 발생한다.
(C++)
void printMessage()
{
printf("Hello, World!\n"); // 이 함수 코드 자체가 코드 영역에 위치함
}
2) 데이터 영역 (Data Segment)
: C/C++에서는 데이터 영역을 크게 초기화 여부에 따라 Data 영역과 BSS 영역 두 가지로 세분화하여 관리한다.
프로그램 시작 시 할당되고 종료 시 시스템이 반환한다.
- 초기화된 데이터 영역 (Data / Initialized Data Segment)
: 초기화 값이 있는 전역 변수, static 변수가 저장된다.
- BSS 영역 (Block Started by Symbol / Uninitialized Data Segment)
: 초기화 값이 없는 전역 변수, static 변수가 저장된다.
프로그램이 시작될 때 모두 0으로 자동 초기화 된다.
(C++)
int global_initialized = 10; // Data 영역 (초기화 됨)
int global_uninitialized; // BSS 영역 (0으로 자동 초기화)
void countCalls()
{
static int count = 0; // Data 영역 (static 변수)
}
3) 힙 영역 (Heap Segment)
: C/C++ 영역에서 프로그래머가 런타임(프로그램 실행 중)에 크기를 결정하여 동적으로 할당하는 공간이다.
포인터를 통해 이 영역에 접근한다.
- C/C++ 특징
- C언어
: malloc(), calloc(), realloc() 함수로 할당하고 free() 로 해제한다.
- C++
: new, new[ ] 연산자로 할당하고 delete, delete[ ] 로 해제한다.
- 메모리 누수 (Memory Leak)
: 사용자가 직접 해제(free / delete) 하지 않으면 프로그램이 종료될 때 까지 메모리를 차지하므로, 메모리 관리에 각별히 유의해야 한다.
(C++)
// C 스타일
int* c_array = (int*)malloc(sizeof(int) * 5); // 힙 영역에 할당
free(c_array); // 반드시 메모리 해제!
// C++ 스타일
int* cpp_array = new int[5]; // 힙 영역에 할당
delete[] cpp_array; // 반드시 메모리 해제!
4) 스택 영역 (Stack Segment)
: 함수 내부에서 선언된 지역 변수(Local Variable)와 함수로 전달되는 매개변수(Parameter)가 저장되는 공간이다.
- C/C++ 특징
- 함수가 호출될 때 여닫는 중괄호 {} 공간 내에서 생성되고, 함수가 종료(return 혹은 중괄호를 벗어남)되면 자동으로 메모리에서 사라진다. (따로 해제할 필요 x)
- 컴파일 타임에 할당할 크기가 정해져 있어야 하므로, C99 이전 컴파일러나 기본 C++에서는 int arr[n]; 처럼 변수를 이용한 가변 배열 선언이 불가능했다. (컴파일러에 따라 다름)
- 스택 크기를 넘어서 너무 깊은 재귀 함수를 호출하거나, 스택에 너무 큰 배열을 선언하면 Stack Overflow가 발생한다.
(C++)
void calculate(int a, int b)
{
// 매개변수 a, b는 스택 영역에 할당
int result = a + b; // 지역 변수 result도 스택 영역에 할당
}
// 함수가 끝나는 순간 a, b, result는 스택에서 완전히 소멸
2. static 키워드
: C/C++에서 static 키워드는 "어디서나 접근할 수 없도록 범위를 제한하되, 프로그램이 끝날 때 까지 메모리에서 유지되도록 보장(정적 할당)" 하고 싶을 때 사용한다.
1) static 지역 변수 (Local Variable)
: 함수 내부나 중괄호 {} 블록 내부에 선언된 static 변수이다.
- 특징
- 생명 주기
: 프로그램이 시작될 때 한 번만 초기화되며, 함수가 종료되어도 메모리에서 소멸하지 않고 값이 유지된다.
다음 함수 호출 시 이전의 최종 값을 그대로 이어받는다.
- 접근 범위 (Scope)
: 일반 지역 변수처럼 해당 함수 내부에서만 접근할 수 있다.
(전역 변수처럼 아무 데서나 수정할 수 없도록 보호하는 효과)
(C++)
void countFunction()
{
static int count = 0; // 프로그램 시작 시 1회만 초기화
count++; std::cout << "호출 횟수: " << count << std::endl;
}
int main()
{
countFunction(); // 출력: 호출 횟수: 1
countFunction(); // 출력: 호출 횟수: 2 (값이 사라지지 않고 유지됨)
}
2) static 멤버 변수와 멤버 함수 (C++ Class)
: C++ 클래스 내부에서 선언되는 static 구성 요소들은 "객체(인스턴스)별로 따로 존재하지 않고, 클래스 전체가 공유한다" 는 공통점이 있다.
① static 멤버 변수 (클래스 변수)
- 특징
- 클래스의 모든 객체가 공동으로 사용하는 하나의 공유 변수이다
- 객체를 여려 개 생성해도 static 멤버 변수는 메모리에 딱 한 개만 만들어진다.
- 주의점
: 클래스 내부 선언은 "설계도" 일 뿐이므로, 반드시 외부에서 별도로 초기화(정의) 해주어야 메모리가 할당된다.
class Marine
{
public:
static int attack_upgrade; // static 멤버 변수 선언 (공유 업그레이드 수치)
int hp = 40; // 일반 멤버 변수 (마린 개별 체력)
};
// 클래스 외부에서 반드시 초기화 필요 (C++ 표준 규칙)
int Marine::attack_upgrade = 0;
int main()
{
Marine m1, m2;
m1.attack_upgrade = 1; // m1을 통해 바꿨지만
std::cout << m2.attack_upgrade << std::endl; // 출력: 1 (m2의 값도 같이 바뀜, 공유되므로)
}
② static 멤버 함수
- 특징
- 객체를 생성하지 않고도 클래스명::함수명() 형태로 직접 호출이 가능한 함수이다.
- 중요 제약
: 객체가 생성되기 전에도 호출할 수 있어야 하므로, 함수 내부에서 일반(non-static) 멤버 변수나 일반 멤버 함수를 사용할 수 없다.
(this 포인터가 존재하지 않기 때문이다.)
Only static 멤버 변수나 static 멤버 함수만 다룰 수 있다.
(C++)
class Game
{
public:
static int user_count;
static void showCount()
{
std::cout << "현재 접속자: " << user_count << std::endl;
// hp = 10; // 에러! 일반 멤버 변수는 접근 불가능
}
};
int Game::user_count = 0;
int main()
{
Game::showCount(); // 객체 생성 없이 클래스 이름으로 바로 호출 가능
}
4) 저장 메모리 영역 (가장 중요)
: static 키워드 붙은 모든 변수(지역 static 변수, 클래스 static 멤버 변수, 전역 static 변수)는 스택(Stack)이나 힙(Heap)이 아닌 데이터 영역(Data Segment)에 저장된다.
- 초기화 유무에 따른 세부 분리
- Data 영역 ( .data)
: static int count = 10; 처럼 초깃값을 명시한 경우 이곳에 저장된다.
- BSS 영역 ( .bss)
: static int count; 처럼 초깃값을 명시하지 않은 경우 이곳에 저장되며, 프로그램 시작 시 자동으로 0으로 초기화 된다.
- 메모리 특징 비교
| 구분 | 일반 지역 변수 | static 지역 / 멤버 변수 |
| 저장 영역 | 스택(Stack) 영역 | 데이터(Data/BSS) 영역 |
| 할당 시점 | 함수가 호출될 때 | 프로그램이 실행(로드) 될 때 |
| 소멸 시점 | 함수가 종료될 때 자동으로 소멸 | 프로그램 자체가 완전히 종료될 때 소멸 |
* 요약
- static 변수는 일반 변수와 달리 함수나 객체의 생명 주기에 종속되지 않고, 프로그램의 시작과 끝을 함께하는 데이터 영역에 붙박이처럼 상주하는 변수다.
'개인 공부' 카테고리의 다른 글
| 06.22 C/C++ 키워드로 개념 정리) extern / 동적 할당 (0) | 2026.06.22 |
|---|---|
| 06.17 Unreal 키워드로 개념 정리) UFUNCTION의 속성 / USTRUCT (0) | 2026.06.17 |
| 06.12 Unreal 키워드로 개념 정리) 직렬화 / GENERATED_BODY (0) | 2026.06.12 |
| 06.10 C/C++ 키워드로 개념 정리) 컴파일 / 게임 프로그래밍 (1) | 2026.06.11 |
| 06.10 Unreal 키워드로 개념 정리) UPROPERTY / UObject (0) | 2026.06.10 |