C++ #09 스마트 포인터

underlier12·2020년 2월 9일
0

C++

목록 보기
9/19

09. 스마트 포인터

스마트 포인터

Smart Pointer는 프로그래머의 실수로 메모리 누수를 방어하기 위한 수단으로 포인터처럼 동작하는 클래스 템플릿이다. 일반적으로 new 키워드를 이용해 기본 포인터가 특정한 메모리 주소를 가리키도록 초기화 한 후 스마트 포인터에 해당 포인터를 넣어서 사용할 수 있다.

스마트 포인터의 종류

  1. unique_ptr : 하나의 스마트 포인터가 특정한 객체를 처리할 수 있도록 한다.
  2. shared_ptr : 특정한 객체를 참조하는 스마트 포인터가 총 몇개인지 참조한다.
  3. weak_ptr : 하나 이상의 shared_ptr 인스턴스가 소유하는 객체에 대한 접근을 제공한다.

unique_ptr

하나의 스마트 포인터만이 특정한 객체를 처리하도록 할 때 unique_ptr을 사용할 수 있다. 이 스마트 포인터는 특정한 객체의 소유권을 가지고 있을 때만 소멸자가 객체를 삭제할 수 있다.

#include<iostream>

using namespace std;

int main(void) {
	unique_ptr<int> p1(new int(10));
	unique_ptr<int> p2;
	cout << "스마트포인터1: " << p1 << '\n';
	cout << "스마트포인터2: " << p2 << '\n';

	cout << "---소유권이전---\n";
	p2 = move(p1); // 소유권이전
	cout << "스마트포인터1: " << p1 << '\n';
	cout << "스마트포인터2: " << p2 << '\n';

	cout << "---메모리할당해제---\n";
	p2.reset(); // 메모리할당해제
	cout << "스마트포인터1: " << p1 << '\n';
	cout << "스마트포인터2: " << p2 << '\n';
	system("pause");
}

shared_ptr

특정한 객체를 새로운 스마트 포인터가 참조할 때마다 참조 횟수가 1씩 증가하며 각 스마트 포인터의 수명이 다할 때마다 1씩 감소한다. 결과적으로 참조 횟수가 0이 되면 delete 키워드를 이용해 메모리에서 데이터를 자동으로 할당 해제한다.

#include<iostream>

using namespace std;

int main(void) {
	int* arr = new int[10];

	shared_ptr<int> p1(arr);
	cout << p1.use_count() << '\n';

	shared_ptr<int> p2(p1);
	cout << p1.use_count() << '\n';

	shared_ptr<int> p3 = p2;
	cout << p1.use_count() << '\n';

	p1.reset();
	p2.reset();
	p3.reset();
	cout << p1.use_count() << '\n';
	system("pause");
}

weak_ptr

일반적으로 서로가 상대방을 가리키는 두 개의 shared_ptr가 있다면 참조 횟수는 0이 될 수 없기 때문에 메모리에서 해제될 수 없다. weak_ptr는 이러한 순환 참조 현상을 제거하기 위한 목적으로 사용할 수 있다.

#include<iostream>

using namespace std;

int main(void) {
	int* arr = new int(1);
	shared_ptr<int> sp1(arr);
	weak_ptr<int> wp = sp1; // wp는 참조횟수계산에서 제외합니다.

	cout << sp1.use_count() << '\n'; // 1로 동일합니다.
	cout << wp.use_count() << '\n';

	if (true) {
		shared_ptr<int> sp2 = wp.lock(); // shared_ptr포인터반환
		cout << sp1.use_count() << '\n';
		cout << wp.use_count() << '\n';
	}

	// 스코프(Scope)를 벗어나므로 sp2가해제됩니다.
	cout << sp1.use_count() << '\n';
	cout << wp.use_count() << '\n';
	system("pause");
}
profile
logos and alogos

0개의 댓글