C++ 공부 (8/21)

wsung·2026년 1월 21일

Day 8 — 동적 메모리 & 스마트 포인터

🎯 오늘 목표

  • 스택(Stack) vs 힙(Heap) 차이 정확히 이해
  • new / delete의 진짜 역할
  • 메모리 주인(ownership) 개념 확립
  • 스마트 포인터가 왜 필수인지 납득

동적 메모리의 필요성

void func(){
	int a= 10;
}

a는

  • 함수 시작 -> 생성
  • 함수 종료 -> 소멸
    => 함수 밖으로 절대 못나감

but

int* createValue(){
	int a = 10;
    return &a; // x
}

힙의 등장이유

  • 함수가 끝나도 살아남는 메모리
int* p = new int(10);

자동삭제는 X

delete 왜 필요?

int *p =new int(10);
delete p;

=> 이 메모리는 이제 필요없다를 명시적으로 선언

delete 안하면??
while(true)
{
	int *p = new int(10);
}

=> 메모리 누수
=> 프로그램은 조용히 죽어감

new/delete의 진짜 문제

  1. 주인 불명확
int *p = new int(10);
func(p);
- func가 delete?
- main이 delete?
  1. 예외 발생시 delete안됨
int*p = new int(10);
throw;
delete p; // 실행 안됨
  1. delete 두번
delete p;
delete p;

그래서 C++이 만든 해답

RALL : 자원의 생명주기를 객체의 생명주기에 묶자

스마트 포인터 등장

이전

int*p = new int(10);
// ...
delete p;

현대

#include <memory>

auto p = std::make_unique<int>(10);
  • delete 없음
  • scope 끝나면 자동 해제
  • 주인 명확

스마트 포인터 3종 정리

unique_ptr : 단독소유 : 사용처 기본
shared_ptr : 공동소유 : 사용처 제한적
weak_ptr : 감시용 : 사용처 순환참조방지

unique_ptr

std::unique_ptr<int> p = std::make_unique<int>(10);
  • 복사 X
  • 이동 O
  • 주인 단 하나

이동ex)

auto p1 = std::make_unique<int>(10);
auto p2 = std::move(p1);

p1->nullptr
p2->메모리

shared_ptr (주의)

	auto p1 = std::make_shared<int>(10);
    auto p2 = p1;
  • 내부 참조 카운트
  • 마지막 하나 없어질때 delete
  • but 순환 참조 시 메모리 안지워짐

weak_ptr (순환 참조 해결)

std::weak_ptr<int> wp = sp;
  • 소유 X, 관찰만

실무 규칙

  1. new/delete는 직접 쓰지말기
  2. 소유권은 타입으로 표현
  3. 기본은 unique_ptr

MFC/winAPI와 연결

CreateThread(
	nullptr,
    0,
    ThreadFunc,
    this, // 포인터
    0,
    nullptr
  • os는 소유 안함
  • 빌려만 씀
  • 그래서 : 누가 delete하는지 항상 명확해야함

RAII : Resource Acquisition Is Initialization

  • 자원을 얻는 순간 객체 생성 자원을 놓는 순간 객체 소멸
profile
0부터 시작하는 백엔드

0개의 댓글