본문 바로가기
C++

스택(Stack)과 힙(Heap) : 책임과 수명의 차이

by Oz Driver 2026. 1. 8.

왜 메모리에는 힙(Heap)이 필요해졌을까?

초기의 프로그램은 작업을 시작하고, 일을 끝내고, 메모리를 함께 정리하는 방식으로 동작했습니다. 이건 메모리가 이런 방식으로 설계되어 있기 때문입니다. 이 방식은 단순하고 빠르며, 실수할 여지도 적었습니다.

문제는 프로그램이 점점 커지면서 생겼습니다. 작업이 끝나도 계속 유지되어야 하는 데이터가 필요해진 것입니다.

 

 • 여러 작업에서 공통으로 사용하는 데이터

 • 언제 사라질지 미리 알 수 없는 데이터

 • 프로그램 전체에서 오래 유지되어야 하는 데이터

 

이런 데이터들은 기존처럼 “작업이 끝나면 무조건 정리되는 메모리” 에 둘 수 없었습니다.

그래서 운영체제는 필요한 만큼 만들고, 원하는 시점까지 유지할 수 있는 메모리 공간을 따로 마련했습니다. 이 공간을 기존 공간과 소프트웨어적으로 구분하기 위해 "힙" (Heap) 이라는 명칭을 사용했으며, 기존 공간은 "스택" (Stack) 이라고 불렀습니다.

 

이후 C++은 운영체제가 제공하는 이 메모리 모델을 프로그래머가 직접 다룰 수 있도록 언어 차원에서 그대로 노출한 언어가 되었습니다. 이제부터는 이 힙이라는 공간이 기존 방식과 어떻게 다르고, 왜 책임의 주체가 달라지는지 살펴보겠습니다.

 

스택과 힙 : 누가 언제까지 책임지는가?

C++ 메모리 관리에서 스택과 힙은 단순히 "어디에 저장되느냐"의 차이가 아니라, "누가 언제까지 책임지느냐" 의 차이입니다.

1. 스택(Stack): 자동으로 관리되는 공간

스택은 함수가 실행되는 동안만 잠시 사용하는 공간입니다.

void Foo()
{
    int gold = 100;
}

 

gold는 함수 Foo가 실행되는 동안만 존재합니다. 함수가 끝나는 순간, 이 변수는 자동으로 사라집니다. 개발자가 따로 정리할 필요도 없고, 정리할 수도 없습니다.

 

 • 비유 : 강의실 안에 있는 '금 두꺼비' 와 같습니다. 강의가 시작되면 나눠주고, 강의가 끝나면 조교가 자동으로 전부 회수해 갑니다.

 • 특징 : 생성과 소멸 시점이 명확하여 빠르고 안전하지만, 함수가 끝나면 반드시 사라집니다.

 • 문제 상황 : 함수가 끝나도 남아 있어야 한다면?

int* CreateGold()
{
    int gold = 100;
    return &gold; // ❌ 위험!
}

 

이 코드는 잘못된 코드입니다. gold 는 함수가 끝나는 순간 사라지는데, 반환된 주소는 이미 사라진 대상을 가리키게 됩니다. 이 주소를 그대로 사용하면 "예측할 수 없는 오류(Crash)"가 발생합니다. 그래서 "함수가 끝나도 남아 있는 공간"이 필요해졌습니다.

2. 힙(Heap) : 개발자가 직접 책임지는 공간

힙은 개발자가 직접 만들고, 직접 없애는 자유로운 공간입니다.

int* gold = new int{100};

// 기존 초기화 방식
int* gold = new int(100);

 

이 코드는 힙에 int 하나를 생성하고 그 주소를 gold 에 저장합니다. new 를 사용하면 내가 원하는 시점에, 원하는 만큼 메모리를 만들 수 있는데 이를 동적 할당이라고 부릅니다.

 

 • 비유 : 강의실 밖 어딘가에 '황금 박쥐 동상'을 세운 것과 같습니다. 직접 들고 다닐 수 없지만, 위치(주소)를 받아두면 언제든 접근할 수 있습니다.

 • 추가 설명 : 여기서 실제 값 100은 힙에 있지만, 그 주소를 담은 변수 gold 자체는 스택(내 손) 에 있습니다. 주소 종이는 쥐고 있고, 실체는 멀리 있는 셈입니다.

 • 힙의 중요한 특징 : 수동 관리 힙 데이터는 함수가 끝나도 자동으로 사라지지 않습니다. 그래서 반드시 직접 정리해야 합니다.

delete gold; // 동상 철거

 

이 코드를 호출하는 순간 힙의 데이터는 제거됩니다. 만약 delete를 잊으면 메모리는 버려진 동상들로 가득 차게 되는데, 이를 "메모리 누수(Memory Leak)" 라고 부릅니다.

3. 주소 공유와 위험성

힙의 또 다른 특징은 여러 변수가 같은 대상을 가리킬 수 있다는 점입니다.

int* a = new int(100);
int* b = a; // 주소 종이 복사

 

여러 사람이 같은 황금 박쥐 동상의 주소를 들고 있는 상태입니다.

누군가 값을 바꾸면 

*b = 200;

 

공유하고 있는 다른 쪽에서도 변화가 보입니다. 하지만 주의할 점이 있습니다.

delete a;

 

를 하는 순간 동상은 철거됩니다. 하지만 b는 여전히 주소 종이를 들고 있습니다.

이 상태에서 *b로 접근하면 이미 사라진 대상을 건드리는 치명적인 오류가 발생합니다.

그래서 실무에서는 delete 이후 해당 주소 변수를 "nullptr" 로 바꿔 두는 습관을 가집니다. 이미 철거된 동상을 다시 찾아가지 않기 위해서입니다.

 

정리하며

 • 스택 : 잠깐 쓰고 끝나는 데이터, 조교(컴파일러)가 자동으로 정리해 주는 공간

 • 힙 : 오래 살아야 하는 데이터, 개발자가 직접 만들고(new) 직접 철거(delete)하는 공간

 

잊지 마세요. 스택은 조교가 치워주지만, 힙은 개발자가 직접 치워야 합니다. 황금 박쥐 동상을 세워 놓고 철거(delete)를 잊는 순간, 메모리는 버려진 동상들로 점점 가득 차게 될 것입니다.

 

 

 

 

 

'C++' 카테고리의 다른 글

객체 초기화 방법  (0) 2026.01.09
new 할당과 초기화  (0) 2026.01.09
복사의 종류와 차이점  (0) 2026.01.08
매크로란 무엇인가?  (0) 2026.01.05
전방 선언  (0) 2026.01.05