스마트 포인터

2024. 12. 24. 17:02·내배캠/C++

Dangling Pointer

 

정의 : 이미 해제되었거나 소멸된 주소를 가리키는 포인터

 

발생 상황:

  • 동적으로 할당된 포인터가 해제 되었음에도 해당 포인터를 계속 사용하려고 할 때
  • 지역 변수가 Stack메모리에 저장되어있다가 해당 함수가 끝나고 소멸되었음에도 불구하고 해당 변수의 주소를 가리킬 때
  • 이중 해제(같은 메모리를 두 번 삭제할 때)와 같은 잘못된 메모리 작업

 

 

 

 

 

 

Smart Pointer

 

Dangling pointer가 발생하지 않도록 C++에서 제공하는 Smart Pointer에 대해 알아보자.

 

Smart pointer의 핵심 원리는 레퍼런스 카운트가 0이 되면 자동으로 메모리를 해제하는 것이다.

그래서 사용자가 직접 delete를 하지 않아도 된다.

 

unique_ptr과 shared_ptr은 <memory> 헤더에 정의되어 있다.

 

1. unique_ptr

*기본적인 사용법

더보기
#include <iostream>
#include <memory>
using namespace std;

void Func()
{
    unique_ptr<int> Ptr1 = make_unique<int>(10);
   

    int a = *Ptr1; // Ptr1이 가리키는 주소의 값을 불러와 다른 지역 변수에 저장 O

    cout << "Ptr1의 값을 저장한 a변수의 값: " << a << endl;

    //unique_ptr<int> Ptr2 = Ptr1 최대 레퍼런스 카운터가 1이기에 복사 X

    unique_ptr<int> Ptr2 = move(Ptr1); // 대신 소유권 이동 가능

    if (!Ptr1)
    {
        cout << "Ptr1이 해제되었습니다." << endl;
    }

    cout << "Ptr2의 값: " << *Ptr2 << endl;
    
    //함수가 종료되면 자동으로 메모리 해제
}
  • 최대 레퍼런스 카운터가 1이어서 복사 및 대입이 불가능하다.
  • move( ) : 소유권 이동시킨다.

 

*일반 클래스에서의 unique_ptr

더보기
#include <iostream>
#include <memory>
using namespace std;

class PtrClass
{
public:
    PtrClass(int Val) : Value(Val)
    {
        cout << "PtrClass 생성" << endl;
    }
    
    ~PtrClass()
    {
        cout << "PtrClass 소멸" << endl;
    }

    void Display() const
    {
        cout << "Value: " << Value << endl;
    }

private:
    int Value;
};

int main()
{
    //unique_ptr로 PtrClass 객체 관리
    unique_ptr<PtrClass> MyObject = make_unique<PtrClass>(30);

    //PtrClass의 멤버 함수 호출
    MyObject->Display();

    //NewOwner 포인터로 PtrClass객체의 소유권 이전
    unique_ptr<PtrClass> NewOwner = move(MyObject);

    //MyObject == nullptr
    if (!MyObject)
    {
        cout << "소유권이 이전 되었습니다." << endl;
    }

    //소유권을 이전 받은 NewOwner로 PtrClass 객체의 멤버 함수 호출
    NewOwner->Display();


    //함수가 종료되면 NewOwner에서 관리하는 메모리 자동으로 해제
    return 0;
}

 

 

 

2. shared_ptr

*일반 클래스에서의 shared_ptr

더보기
#include <iostream>
#include <memory>
using namespace std;

class PtrClass
{
public:
    PtrClass(int Val) : Value(Val)
    {
        cout << "PtrClass 생성" << endl;
    }
    
    ~PtrClass()
    {
        cout << "PtrClass 소멸" << endl;
    }

    void Display() const
    {
        cout << "Value: " << Value << endl;
    }

private:
    int Value;
};

int main()
{
    //shared_ptr로 PtrClass객체 관리
    shared_ptr<PtrClass> Object1 = make_shared<PtrClass>(50);

    //레퍼런스 공유
    shared_ptr<PtrClass> Object2 = Object1;

    cout << "Object1과 Object2의 레퍼런스 카운트: " << Object1.use_count() << endl;

    //Object1 해제하여도 Object2가 객체를 유지
    Object1.reset();

    if (!Object1)
    {
        cout << "Object1은 해제되어 nullptr 입니다." << endl;
    }

    cout << "Object1 해제 후, Object2의 레퍼런스 카운트: " << Object2.use_count() << endl;

    Object2->Display();
   
    return 0;
}
  • 레퍼런스 카운터가 N개가 될 수 있는 Smart pointer 이므로, 복사와 대입 등이 가능하다.
  • use_count( ) : 레퍼런스 카운터 갯수를 볼 수 있는 함수
  • reset( ) : 해당 포인터를 초기화 시킬 수 있는 함수

 

'내배캠 > C++' 카테고리의 다른 글

std::transform  (1) 2024.12.26
템플릿 함수  (0) 2024.12.24
Stack / Static / Heap  (2) 2024.12.24
가상 함수와 추상 클래스  (0) 2024.12.24
Quick Sort 정렬 알고리즘  (0) 2024.12.23
'내배캠/C++' 카테고리의 다른 글
  • std::transform
  • 템플릿 함수
  • Stack / Static / Heap
  • 가상 함수와 추상 클래스
동그래님
동그래님
  • 동그래님
    개발자 동그래
    동그래님
  • 전체
    오늘
    어제
    • 분류 전체보기 (210)
      • 공부 (51)
        • Code Cata (50)
      • 내배캠 (151)
        • TIL (50)
        • C++ (37)
        • Unreal Engine (48)
        • GAS(Gameplay Ability System.. (16)
      • Project (7)
        • Gunfire Paragon (5)
        • Arena Fighters (1)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    동그래님
    스마트 포인터
    상단으로

    티스토리툴바