Programming

[C/C++] std::shared_ptr

Trunk 2023. 4. 16. 13:51

공용 포인터 (shared_ptr) 는 참조 카운트가 0의 상태가 되면

메모리에서 해제되도록 설계된 클래스이다.

사용 목적 : heap 할당 메모리를 해제를 하지 않아 발생하는 "메모리 릭"을 최소화 할 수 있다. 하지만 순환 참조가 되어버리면 해제할 수 없으므로 코딩에 주의를 기울여야 한다.

 

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <iostream>
#include <map>
//#include <atomic>
#include <functional>
 
 
template< class T >
class Caching_InMemory
{
public:
    void Update(std::function<* (void)> get_data_func)
    {
        std::shared_ptr<T> data(get_data_func());
        std::atomic_store(&data_, data);
    }
 
    const std::shared_ptr<T> Get()
    {
        return std::atomic_load(&data_);
    }
 
private:
    std::shared_ptr<T> data_;
};
 
 
/************************
//    샘플 코드 시작
*************************/
struct character
{
    int playerID;
    int level;
    int exp;
    int HP;
 
    character(int id) : playerID(id)
    {
        level = 1 + id;
        exp = 50 * id;
        HP = 50 * id;
    }
};
 
int main()
{
    std::map<intstd::shared_ptr<character>> playerList;
 
    //Example 01 : 공용 포인터 (참조 카운트) 기본 사용
    for (int i = 0; i < 10++i)
    {
        auto player = std::make_shared<character>(i);
 
        playerList.insert({i, player});
    }
 
    for (int i = 0; i < 10++i)
    {
        auto itrPlayer = playerList.find(i);
        playerList.erase(i);
    }
    
    //Example 02 : 데이터 관리용 클래스 (공용 포인터)
    Caching_InMemory<character> dataManager;
    dataManager.Update([=]()->character* {
        return new character(1);
        });
    
    std::cout << "playerID : " << dataManager.Get()->playerID 
<< ", Memory : " << &dataManager.Get()->playerID << std::endl;
 
    // 데이터 변경(std::atomic_store)으로 
    // 이전 데이터 참조 카운트 0으로 만들기.
    dataManager.Update([=]()->character* {
        return new character(2);
        });
 
    std::cout << "playerID : " << dataManager.Get()->playerID 
<< ", Memory : " << &dataManager.Get()->playerID << std::endl;
    return 0;
}
cs