[C++] 스마트 포인터

2024. 12. 26. 22:11·C++/Basic

1. 용어

  • 복사 : 객체 생성시 다른 객체로부터 데이터를 복사한다.
  • 얕은 복사 : 가리키는 객체의 주소를 복사하여 참조한다.
  • 깊은 복사 : 가리키는 객체의 데이터를 복사하여 독립적으로 참조한다.

 

2. 스마트 포인터

2-0. 포인터 에러

포인터는 할당되지 않은 메모리에 할당해제를 할 경우 런타임 에러가 발생하고
프로그램이 비정상으로 종료되거나 메모리 손상이 발생할 수 있다.

 

2-1. 포인터 대신 스마트 포인터?

포인터에 저장된 주소만으로 현재 객체가 할당되었는지 할당되지 않았는지 확인할 수 없다.

프로그램이 복잡해지면 여러 포인터가 하나의 객체를 참조하게 되는데 향후 어떤 포인터가 할당 해제할 지 고민하게 된다.

포인터1 : 내가 먼저 할당했음으로 내가 할당 해제를 하지!
포인터2 : 잠시만... 나는 아직 해당 객체를 사용하고 있어.
포인터1 : 그러면 2번이 사용을 끝내고 할당해제할까?
포인터3 : 기다려! 나도 아직 사용 중이야

 

메모리를 관리하기 위해 어느 순간 할당 해제를 해야한다. 그 순간이란 언제일까?

 

2-2. 스마트 포인터

위 문제를 해결하기 위해 모든 포인터가 사용을 완료하였는지 확인해야한다.

하지만 수많은 코드에서 현재 어떤 포인터가 객체를 가리키고 있는지 찾아내는 것은 쉽지 않다.

"그러면 객체를 참조하는 포인터들을 기록하자"

스마트 포인터는 포인터를 감싸는 레퍼 클래스이다.

그리고 객체를 몇 명이 참조하고 있는지 기록하고 있으며 이를 레퍼런스 카운터라고 한다.

 

2-3. 레퍼런스 카운터

레퍼런스 카운터로 어떻게 할당 해제를 안전하게 할 수 있을까?

레퍼런스 카운터는 0이 되면 자동으로 할당해제를 한다.

스마트 포인터1 : 참조 (카운트 1)
스마트 포인터 2 : 참조 (카운트 2)
스마트 포인터 3 : 참조 (카운트 3)
스마트 포인터 2 : 참조 해제 (카운트 2)
스마트 포인터 3 : 참조 해제 (카운트 1)
스마트 포인터 1: 참조 해제 (카운트 0 = 할당 해제)

 

3. unique_ptr

레퍼런스 카운터를 최대 1까지 허용된다.

하나의 객체를 하나의 포인터만이 참조한다는 것을 보장한다.

 

unique_ptr 생성

#include <memory>

unique_ptr<int> ptr = make_unique<int>(10);

 

unique_ptr 소유권 이전 (move)

unique_ptr<int> ptr = make_unique<int>(10);
unique_ptr<int> ptr2 = std::move(ptr);

if (!ptr) cout << "소유권 이전 완료";

 

Unique_ptr 주의할 점

unique_ptr은 복사가 불가능하다.

복사를 허용하면 레퍼런스 카운터는 2이상이 된다.

unique_ptr<int> ptr2 = ptr1; //  컴파일 에러 발생!

 

4. shared_ptr

레퍼런스 카운터를 여러개 허용한다.

 

shared_ptr 생성

#include <memory>

shared_ptr<int> ptr = make_shared<int>(10);

 

Shared_ptr 레퍼런스 복사

shared_ptr<int> ptr = make_shared<int>(10);
shared_ptr<int> ptr2 = ptr;

 

shared_ptr 레퍼런스 카운터 개수 확인

ptr.use_count();

 

shared_ptr 레퍼런스 참조 해제

shared_ptr<int> ptr = make_shared<int>(10); // 레퍼런스 카운트 1
shared_ptr<int> ptr2 = ptr; // 레퍼런스 카운트 2

ptr2.reset(); // 레퍼런스 카운트 1

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

[C++] 함수 오버로딩과 템플릿  (0) 2024.12.26
[C++] 객체지향 프로그래밍  (0) 2024.12.25
[C++] Class  (0) 2024.12.25
'C++/Basic' 카테고리의 다른 글
  • [C++] 함수 오버로딩과 템플릿
  • [C++] 객체지향 프로그래밍
  • [C++] Class
DevColIn
DevColIn
복잡함을 단순하게
  • DevColIn
    심플한 코딩생활
    복잡함을 단순하게
  • 전체
    오늘
    어제
    • 전체보기 (223)
      • Unreal 부트캠프 (49)
        • TIL (34)
        • 사전캠프 (7)
        • 본캠프 (8)
      • Unrael (10)
        • 환경설정 (0)
        • Basic (19)
        • Component (5)
        • GAS (GameplayAbilitySystem) (3)
        • AI (2)
        • Implement (10)
        • UI (1)
        • Error (1)
        • Network (2)
        • Tip (1)
      • Level Design (5)
      • Math (1)
      • Design Pattern (16)
      • Computer Science (2)
        • Network (1)
        • Database (1)
      • Algorithm (79)
        • Basic (4)
        • Practice (74)
      • C++ (4)
        • Basic (4)
      • Tool (0)
      • Game (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    내일배움캠프
    Implement
    gas
    사전캠프
    AI
    액터
    디자인 패턴
    소프트 레퍼런신
    Animation
    unreal
    알고리즘
    레벨디자인
    Design Pattern
    게임동기화
    c++
    basic
    Til
    GameplayEffect
    unrealengine
    assetmanager
    actor
    tsoftobjectptr
    디자인패턴
    component
    DesignPattern
    본캠프
    하드 레퍼런싱
    KPT회고
    Algorithm
    퀘스트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
DevColIn
[C++] 스마트 포인터
상단으로

티스토리툴바