- 효율적인 메모리 관리를 위해 만들어진 객체입니다.
- 참조 카운트 방식으로 메모리 해제를 결정합니다. (0이 되면 해제)
기본 사용법
#include <iostream>
#include <memory>
int main() {
std::shared_ptr<int> ptr1 = std::make_shared<int>();
std::cout << "memory address : "
<< ptr1 << std::endl;
std::cout << "memory value : "
<< *ptr1 << std::endl;
return 0;
}
/* OUTPUT
memory address : 0x55744002aec0
memory value : 0
*/
참조 카운트 움직임
#include <iostream>
#include <memory>
void RefCountTest(std::shared_ptr<int> param) {
std::cout << "ref count after param transmission : "
<< param.use_count() << std::endl;
std::shared_ptr<int> localPtr = param;
std::cout << "ref count after local reference : "
<< param.use_count() << std::endl << std::endl;
}
int main() {
std::shared_ptr<int> ptr1 = std::make_shared<int>();
std::cout << "memory address : "
<< ptr1 << std::endl;
std::cout << "memory value : "
<< *ptr1 << std::endl << std::endl;
RefCountTest(ptr1);
std::cout << "ref count after finished function : "
<< ptr1.use_count() << std::endl;
return 0;
}
/* OUTPUT
memory address : 0x55746e45dec0
memory value : 0
ref count after param transmission : 2
ref count after local reference : 3
ref count after finished function : 1
*/
소멸자 중복 호출에서 벗어나기
#include <iostream>
#include <memory>
class duplicationDestroy {
public:
duplicationDestroy() {
data = new int[10];
std::cout << "Called Constructor!!" << std::endl;
}
~duplicationDestroy() {
std::cout << "Called Destroy." << std::endl;
delete[] data;
}
private:
int* data;
};
int main() {
duplicationDestroy* allocData = new duplicationDestroy();
std::shared_ptr<duplicationDestroy> ptr1(allocData);
std::shared_ptr<duplicationDestroy> ptr2(allocData);
std::cout << ptr1.use_count() << std::endl;
std::cout << ptr2.use_count() << std::endl;
return 0;
}
/* OUTPUT
Called Constructor!!
1
1
Called Destroy.
Called Destroy.
메모리 해제를 했는데 다시 하기 때문에 에러이고,
이로인해 스레드 방식의 운영이면 Exception이 발생이 가능합니다.
*/
- std::enable_from_this<T> 상속 받아서 사용하면 됩니다.
#include <iostream>
#include <memory>
class duplicationDestroy : public std::enable_shared_from_this<duplicationDestroy> {
public:
duplicationDestroy() {
data = new int[10];
std::cout << "Called Constructor!!" << std::endl;
}
~duplicationDestroy() {
std::cout << "Called Destroy." << std::endl;
delete[] data;
}
private:
int* data;
};
int main() {
//duplicationDestroy* allocData = new duplicationDestroy();
std::shared_ptr<duplicationDestroy> ptr1 = std::make_shared<duplicationDestroy>();
std::cout << "ptr1 use_count : "
<< ptr1.use_count() << std::endl;
std::shared_ptr<duplicationDestroy> ptr2 = ptr1;
std::cout << "ptr1 use_count : "
<< ptr1.use_count() << std::endl;
std::cout << "ptr2 use_count : "
<< ptr2.use_count() << std::endl;
return 0;
}
/* OUTPUT
Called Constructor!!
ptr1 use_count : 1
ptr1 use_count : 2
ptr2 use_count : 2
Called Destroy.
*/
순환 참조라면 std::weak_ptr을 이용하자.
#include <iostream>
#include <memory>
class SharedTest {
std::weak_ptr<SharedTest> ptr1;
public:
SharedTest() {
std::cout << "initialize resource!!" << std::endl;
}
~SharedTest() {
std::cout << "Destroy resource!" << std::endl;
}
void SetPtr(std::shared_ptr<SharedTest> param) {
ptr1 = param;
}
};
int main() {
std::shared_ptr<SharedTest> pa1 = std::make_shared<SharedTest>();
std::shared_ptr<SharedTest> pa2 = std::make_shared<SharedTest>();
pa1->SetPtr(pa2);
pa2->SetPtr(pa1);
std::cout << pa1.use_count() << std::endl;
std::cout << pa2.use_count() << std::endl;
return 0;
}
/* OUTPUT
initialize resource!!
initialize resource!!
1
1
Destroy resource!
Destroy resource!
*/
'IT 개발 노트 > PROGRAMMING' 카테고리의 다른 글
리팩토링할 때 알아두면 좋은 정보 (1) | 2025.01.24 |
---|---|
[Debug] 원격 디버깅 (0) | 2024.12.18 |
[C++] unix_timestamp 값을 날짜와 시간으로 변경하기 (0) | 2024.12.09 |
[visual studio] SSDT (SQL Server Data Tools) (1) | 2024.11.29 |
[visual studio] 프로젝트 멀티 실행 (디버그 모드) (1) | 2024.11.29 |