C++ 변수 생명주기와 스코프
1. 개요
1.1 문서 개요
이 문서는 C++에서 변수의 생명주기(Lifetime)와 스코프(Scope)에 대해 설명합니다. 변수의 생명주기는 메모리에 존재하는 시간 동안의 유효성을 의미하고, 스코프는 소스 코드 내에서 변수에 접근 가능한 범위를 의미합니다. 이 두 개념은 메모리 관리, 객체 수명 제어, 버그 방지 등 다양한 측면에서 중요한 역할을 수행합니다.
2. 내용
2.1 변수의 스코프 (Scope)
2.1.1 블록 스코프
지역 변수는 블록({}) 내부에서 선언되며, 해당 블록의 끝에서 소멸됩니다.
void func() {
int x = 10; // x는 func 블록 내에서만 유효
}
2.1.2 함수 스코프
함수 이름, 인자 등은 함수 전체에서 유효합니다. 함수 인자는 해당 함수 내부에서만 접근할 수 있습니다.
void add(int a, int b) {
// a, b는 add 함수 내부에서만 사용 가능
}
2.1.3 파일 스코프
전역 변수는 파일 전체에서 유효합니다.
int globalVar = 100; // 파일 내 모든 함수에서 접근 가능
2.1.4 네임스페이스 스코프
C++에서는 변수나 함수가 네임스페이스에 속할 수 있으며, 이는 명시적 범위를 정의하는 데 사용됩니다.
namespace MyNamespace {
int value = 42;
}
2.2 변수의 생명주기 (Lifetime)
2.2.1 자동 변수 (자동 생명주기)
일반적인 지역 변수는 함수 호출 시 생성되고, 함수 종료 시 소멸됩니다.
void func() {
int a = 10; // 자동 변수, 스택에 할당됨
}
2.2.2 정적 변수 (정적 생명주기)
static
키워드로 선언된 변수는 한 번만 초기화되며, 프로그램 종료 시까지 유지됩니다.
void counter() {
static int count = 0;
++count;
std::cout << count << std::endl;
}
2.2.3 동적 변수 (동적 생명주기)
new
또는 malloc
으로 생성된 객체는 수동으로 삭제할 때까지 메모리에 유지됩니다.
int* p = new int(5); // 동적 할당
delete p; // 수동 해제 필요
2.3 스코프와 생명주기의 상호 작용
2.3.1 지역 객체의 반환 오류
함수 내 지역 변수의 주소를 반환하는 경우, 해당 주소는 더 이상 유효하지 않음
int* getPointer() {
int x = 10;
return &x; // 위험: x는 함수 종료 시 소멸
}
2.3.2 정적 지역 변수의 공유
static
지역 변수는 함수 호출 간 값을 유지함
void visitCounter() {
static int visits = 0;
++visits;
std::cout << "Visits: " << visits << std::endl;
}
2.3.3 전역 변수의 초기화 순서 문제
다수의 전역 변수 간 종속성이 있는 경우, 초기화 순서로 인한 문제가 발생할 수 있음
2.4 RAII와 스코프 기반 자원 관리
2.4.1 개념
RAII(Resource Acquisition Is Initialization)는 객체가 생성될 때 자원을 확보하고, 소멸될 때 자원을 해제하는 C++의 자원 관리 패턴입니다.
std::ifstream file("data.txt"); // 생성 시 파일 열림
// 스코프 벗어나면 자동으로 파일 닫힘
3. 마무리
C++에서 변수의 생명주기와 스코프는 객체가 존재하는 범위와 기간을 정의하며, 메모리 효율성과 프로그램 안정성에 직접적인 영향을 줍니다. 자동, 정적, 동적 변수는 각각 다른 생명주기를 가지며, 스코프에 따라 접근 가능성 또한 달라집니다. 이러한 개념을 명확히 구분하고 설계에 반영하는 것은 안정적인 C++ 프로그램 개발의 기본 요소입니다.