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 |