반응형
Static 함수
static 함수는 Heap이나 Stack 영역이 아닌 Code 영역에 위치한다. Code 영역에 위치하기 때문에 읽기 전용(Read-Only)이며 그 내용이 변경되지 않음을 보장한다. 그래서 Thread-Safe 하고 안정성이 높다. 변경될 여지가 없기 때문이다.
- 클래스 안에 정의된 전역 함수
- 전역 함수이기 때문에 인스턴스를 생성하지 않아도 접근 및 호출 가능
- 해당 클래스로 선언된 모든 객체에서 공용으로 사용 가능
- 공용으로 사용하기 때문에 아무리 많은 인스턴스가 생성되어도 오직 한개만 존재한다.
- 멤버변수에 접근할 수 없다.
- This 포인터가 없기 때문에 const 키워드를 사용할 수 없다.
Static 변수
static 변수는 Heap이나 Stack 영역이 아닌 Data 영역에 위치한다. static 함수와 같은 위치가 아닌 Data 영역에 위치하는 이유는 static 함수는 내용이 변경되지 않는 읽기 전용 데이터인데 반해 static 변수는 내용이 얼마든지 변경될 수 있기 때문이다.
- 클래스 안에 정의된 전역 변수
- 전역 변수이기 때문에 인스턴스를 생성하지 않아도 접근 및 호출 가능
- 해당 클래스로 선언된 모든 객체에서 공용으로 사용 가능
- 공용으로 사용하기 때문에 아무리 많은 인스턴스가 생성되어도 오직 한개만 존재한다.
- 프로그램 시작시 생성되어서 프로그램 종료 시 소멸한다.
예제 코드
class MyClass
{
public:
MyClass() = default;
~MyClass() = default;
int a;
static int b;
static void Foo();
};
int main()
{
std::cout << "hello, world." << std::endl;
MyClass::b = 1;
MyClass::Foo();
}
Static 함수는 오직 하나라면 Static 변수처럼 객체들이 공유해서 쓰는 것인가?
아니다. static 함수를 하나라고 부르는 이유는 객체(인스턴스)의 상태에 의존하지 않기 때문이다.
- 메모리 공간의 단일성 : 일반 멤버 함수(non-static)는 호출 시 눈에 보이지 않는 this 포인터를 인자로 전달받아 어떤 객체의 데이터를 쓸지 결정한다. 하지만 static 함수는 this 포인터 자체가 없으므로, 어떤 객체가 호출하든 똑같은 로직을 똑같은 방식으로 처리한다.
- 호출 권한 : 객체가 없어도 클래스 이름만으로 호출할 수 있다는 점 때문에 "클래스에 속한 단 하나의 함수"라고 표현한다.
- 스레드 관점 : 스레드 A가 static 함수를 호출한다. > 스레드 A의 Stack에 스택 프레임이 생긴다.
스레드 B가 동시에 static 함수를 호출한다. > 스레드 B의 Stack에 스택 프레임이 생긴다.
이때, 함수 내부에서 지역 변수 혹은 인자만을 사용한다면 각자의 스택 프레임 안에서만 데이터가 변경되기 때문에 서로 간섭 없이 안전하다. 하지만 함수 내부에서 static 멤버 변수(Data 영역)를 건드린다면 두 스레드가 공유 메모리를 접근하는 것이기 때문에 문제가 발생한다.
정리하자면
| 메모리 영역 | 저장되는 것 | 누구의 소유인가? | 특징 |
| Code | static 함수 코드, 일반 함수 코드 | 프로세스 공통 | 읽기 전용, 하나만 존재 |
| Data | static 변수, 전역 변수 | 프로세스 공통 | 모든 스레드가 공유(수정시 위험) |
| Heap | new로 생성된 객체 | 프로세스 공통 | 모든 스레드가 주소만 알면 접근 가능 |
| Stack | 스택 프레임(지역 변수) | 개별 스레드 | 자기 것만 볼 수 있음(안전) |
같이 읽으면 좋은 글
메모리 구조(Memory Structure)에 대해서
메모리 구조우리가 exe 파일을 실행하면 운영체제는 프로그램에 정의된 명령어(코드)를 바탕으로 메모리에 프로세스를 적재(Load)한다. 그리고 해당 프로세스를 위한 Code, Data, Heap, Stack 영역이 생
jettstream.tistory.com
'프로그래밍 > C++' 카테고리의 다른 글
| C++ std::shared_ptr 댕글링 포인터 발생 상황 (0) | 2026.06.03 |
|---|---|
| C++ operator[] 배열 인덱스 연산자 톺아보기 (1) | 2026.04.15 |
| C++ *와 & 연산자 톺아보기 (0) | 2026.03.29 |
| C++ 역참조 연산자와 화살표 연산자에 대해 (0) | 2026.03.29 |
| C++ operator<< 삽입 연산자 톺아보기 (0) | 2026.03.14 |
댓글