일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- pwncollege
- Leviathan
- 취약점
- wargame
- 리눅스 커널
- 어셈블리어
- 시스템
- 알고리즘
- 리눅스커널
- radare2
- write up
- 시스템해킹
- 드론
- kernel
- 워게임
- 프로그래밍
- 컴퓨터구조
- C언어
- Pwnable.kr
- Bandit
- 커널
- 리눅스
- 리버싱
- pwn.college
- 시그널
- 시스템프로그래밍
- css
- px4
- C++
- 시스템 프로그래밍
- Today
- Total
Computer Security
#11 C++ 스마트 포인터 본문
스마트 포인터
C++의 스마트 포인터(Smart Pointer)는 프로그래머의 실수로 메모리 누수(Memory Leak)을 방어하기 위한 수
단으로, 포인터처럼 동작하는 클래스 템플릿(Class Template)이다.
기본적으로 힙 영역에 동적 할당된 메모리를 해제하기 위해서는 delete 키워드를 쓰면 된다.
스마트 포인터를 이용하면 메모리 누수를 더 효과적으로 방지할 수 있기 때문에 컴퓨터 시스템의 안정성을 높일 수 있다.
일반적으로 new 키워드를 이용해서 기본 포인터가 특정한 메모리 주소를 가리키도록 초기화 한 이후에 스마트 포인
터에 해당 포인터를 넣어서 사용할 수 있다.
이렇게 정의된 스마트 포인터는 수명을 다했을 때 소멸자가 delete 키워드를 이용해 할당된 메모리들을 자동으로 해
제하는 기능을 수행한다.
종류
- unique_ptr: 하나의 스마트 포인터가 특정한 객체를 처리할 수 있도록 한다.
- shared_ptr: 특정한 객체를 참조하는 스마트 포인터가 총 몇 개인지를 참조한다.
- weak_ptr: 하나 이상의 shared_ptr 인스턴스가 소유하는 객체에 대한 접근을 제공한다.
unique_ptr
C++에서 하나의 스마트 포인터만이 특정한 객체를 처리하도록 할 때 unique_ptr를 사용할 수 있다.
이러한 스마트 포인터는 특정한 객체의 소유권을 가지고 있을 때만 소멸자가 객체를 삭제할 수 있다.
unique_ptr: 소유권 이전과 메모리 할당 해제
코드 예시
#include <iostream>
using namespace std;
int main(void) {
unique_ptr<int> p1(new int(10)); //p1에 10이라는 동적할당 메모리가 선언가르켜진 상태.
unique_ptr<int> p2; //여긴 지금은 아무것도 가르켜지지 않은 상태이다.
cout << "스마트 포인터 1: " << p1 << '\n'; //10에대한 메모리값 반환
cout << "스마트 포인터 2: " << p2 << '\n'; // 0
cout << "--- 소유권 이전 ---\n";
p2 = move(p1); // move 함수를 이용해 소유권을 p1에서 p2로 이전한다.
cout << "스마트 포인터 1: " << p1 << '\n'; // 0
cout << "스마트 포인터 2: " << p2 << '\n'; // 10에대한 메모리값이 반환
cout << "--- 메모리 할당 해제 ---\n";
p2.reset(); // reset함수를 이용해 메모리 할당 해제
cout << "스마트 포인터 1: " << p1 << '\n'; // 0
cout << "스마트 포인터 2: " << p2 << '\n'; // 0
system("pause");
}
결과 값
unique_ptr: 객체에 접근하기
코드 예시
#include <iostream>
using namespace std;
int main(void) {
unique_ptr<int> p1(new int(10));
cout << *p1 << '\n'; // 관리하고 있는 객체를 반환합니다.
system("pause");
}
결과 값
unique_ptr: 메모리 해제 이후에 객체 접근
코드 예시
#include <iostream>
using namespace std;
int main(void) {
int* arr = new int[10]; //10동적메모리 할당
unique_ptr<int> p1(arr); //그걸 p1이라는 유니크 포인터가 가르킴
for (int i = 0; i < 10; i++) {
arr[i] = i;
} //잘 출력되겠지?
for (int i = 0; i < 10; i++) {
cout << arr[i] << ' ';
}
p1.reset(); //동적 메모리 할당을 해제 해버림.
cout << '\n';
for (int i = 0; i < 10; i++) {
cout << arr[i] << ' '; //쓰레기 값 나옴
}
system("pause");
}
결과 값
shared_ptr
C++에서 shared_ptr은 하나의 특정한 객체를 참조하는 스마트 포인터의 개수가 몇 개인지를 참조한다.
특정한 객체를 새로운 스마트 포인터가 참조할 때마다 참조 횟수(Reference Count)가 1씩 증가하며, 각 스마트 포
인터의 수명이 다할 때마다 1씩 감소한다.
결과적으로 참조 횟수가 0이 되면 delete 키워드를 이용해 메모리에서 데이터를 자동으로 할당 해제한다.
use_count는 현재 참조하고 있는 객체의 개수를 나타내준다.
코드 예시
#include <iostream>
using namespace std;
int main(void) {
int* arr = new int[10]; //10 메모리 할당
shared_ptr<int> p1(arr); // p1이 arr메모리 가르킴
cout << p1.use_count() << '\n'; // p1 한개 밖에 안가르키는중
shared_ptr<int> p2(p1); //p2도 p1을 가르킴 현재 그럼 arr는 p1 p2둘다 가르키는중
cout << p1.use_count() << '\n'; // p1 p2 두개가 가르키는중
shared_ptr<int> p3 = p2; //이번엔 p3도 가르킨대
cout << p1.use_count() << '\n'; //p1 p2 p3 총 3개가 가르킴
p1.reset();
p2.reset();
p3.reset(); //p1 p2 p3 전부 메모리할당 해제
cout << p1.use_count() << '\n'; //전부 메모리가 할당해제됐으니, 가르키는건 없다. 즉 0 도출
system("pause");
}
결과 값
weak_ptr
C++에서 weak_ptr은 하나 이상의 shared_ptr 객체가 참조하고 있는 객체에 접근할 수 있다.
하지만 해당 객체의 소유자의 수에는 포함되지 않는 스마트 포인터다.
일반적으로 서로가 상대방을 가리키는 두 개의 shared_ptr이 있다면, 참조 횟수는 0이 될 수 없기 때문에 메모리에
서 해제될 수 없다.
weak_ptr은 이러한 순환 참조(Circular Reference) 현상을 제거하기 위한 목적으로 사용할 수 있다.
코드 예시
#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");
}
결과 값
'프로그래밍 > C++' 카테고리의 다른 글
#13 C++ STL 시퀀스 컨테이너 라이브러리 (0) | 2022.06.24 |
---|---|
#12 C++ STL 컨테이너 어댑터 라이브러리 (0) | 2022.06.23 |
#10 C++ 템플릿 (0) | 2022.06.21 |
#9 다형성 기법 2 (0) | 2022.06.20 |
#8 C++ 다형성 기법 1 (0) | 2022.06.19 |