๐ ํฌ์ธํฐยท๋ ํผ๋ฐ์ค ์ฌ์ธต ๋ถ์ โ ๋๊ธ๋งยท๋ฉ๋ชจ๋ฆฌ ํฌ๊ธฐยท๋ฐํ์ ์ค๋ฅ
๊ธฐ๋ฐ ํ์ผ: 07_pointer_reference.md ์์ฑ ๊ธฐ์ค: 2026-04-23 ๋ชจ์๋ฉด์ ์ถ๊ฐ ๋ถ์
๋ชฉ์ฐจ
- ๋๊ธ๋ง ํฌ์ธํฐ โ ์๋ชป๋ ์ฃผ์ ์ ๊ทผ
- ํฌ์ธํฐ ๋ฉ๋ชจ๋ฆฌ ํฌ๊ธฐ โ 32๋นํธ vs 64๋นํธ
- ๋ ํผ๋ฐ์ค์์ ๋ฐํ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์๊น?
- ๋๊ธ๋ง ํฌ์ธํฐ ๋ฐฉ์ง ํค์๋ยทํจํด
- ์ธ๋ฆฌ์ผ์์์ ๋๊ธ๋ง ํฌ์ธํฐ
- ํต์ฌ ์์ฝ ์นด๋
1. ๋๊ธ๋ง ํฌ์ธํฐ โ ์๋ชป๋ ์ฃผ์ ์ ๊ทผ
Q: โ๋๊ธ๋ง ํฌ์ธํฐ๊ฐ ๋ฌด์์ด๊ณ , ์ด๋ค ์ํฉ์์ ๋ฐ์ํ๋์?โ
์ ์
๋๊ธ๋ง ํฌ์ธํฐ(Dangling Pointer): ํ๋ ์ ํจํ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌ์ผฐ์ผ๋, ๊ทธ ๊ฐ์ฒด๊ฐ ํด์ (freed) ๋๋ ์๋ฉธ(destroyed)๋ ๋ค์๋ ๋จ์ ์๋ ํฌ์ธํฐ.
1
2
3
| ์ ํจํ ํฌ์ธํฐ: p โโโ [ 42 | ์ด์์๋ ๊ฐ์ฒด ]
ํด์ ํ: p โโโ [ ?? | ํด์ ๋ ๋ฉ๋ชจ๋ฆฌ ] โ ๋๊ธ๋ง!
โ ์ด ์ฃผ์๋ฅผ ์ญ์ฐธ์กฐํ๋ฉด UB
|
๋ฐ์ ์๋๋ฆฌ์ค 3๊ฐ์ง
โ delete ํ ๋ฏธ์ด๊ธฐํ
1
2
3
4
5
6
7
| int* p = new int(42);
delete p; // ํ ๋ฉ๋ชจ๋ฆฌ ํด์
// p๋ ์ฌ์ ํ ๊ฐ์ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์์ โ ๋๊ธ๋ง!
*p = 10; // ๐ฅ UB: ํด์ ๋ ๋ฉ๋ชจ๋ฆฌ ์ฐ๊ธฐ
std::cout << *p; // ๐ฅ UB: ํด์ ๋ ๋ฉ๋ชจ๋ฆฌ ์ฝ๊ธฐ
delete p; // ๐ฅ Double Free โ ํ๋ก๊ทธ๋จ ํฌ๋์
|
โก ์คํ ๋ณ์ ์ฃผ์ ๋ฐํ
1
2
3
4
5
6
7
| int* GetDangling() {
int local = 42; // ์คํ์ ํ ๋น
return &local; // ํจ์ ์ข
๋ฃ ์ local ์๋ฉธ
} // ์คํ ํ๋ ์ ํด์
int* p = GetDangling();
std::cout << *p; // ๐ฅ UB: ์ด๋ฏธ ์๋ฉธ๋ ์คํ ๋ณ์
|
โข ์ปจํ
์ด๋ ์ฌํ ๋น ํ ์ดํฐ๋ ์ดํฐ/ํฌ์ธํฐ
1
2
3
4
5
6
7
| std::vector<int> v = {1, 2, 3};
int* p = &v[0]; // v ๋ด๋ถ ๋ฐฐ์ด์ ์ฒซ ๋ฒ์งธ ์์
v.push_back(4); // ๐ฅ ๋ด๋ถ ๋ฐฐ์ด ์ฌํ ๋น ๋ฐ์ ๊ฐ๋ฅ
// p๋ ์ด์ ํด์ ๋ ๊ตฌ ๋ฐฐ์ด์ ๊ฐ๋ฆฌํด โ ๋๊ธ๋ง!
std::cout << *p; // UB
|
๋๊ธ๋ง ํฌ์ธํฐ ์ญ์ฐธ์กฐ ๊ฒฐ๊ณผ
| ์ํฉ | ๊ฐ๋ฅํ ๊ฒฐ๊ณผ |
|---|
| ์ฝ๊ธฐ | ์ฐ๋ ๊ธฐ ๊ฐ ๋ฐํ, ๋ค๋ฅธ ๋ฐ์ดํฐ ์ฝ๊ธฐ |
| ์ฐ๊ธฐ | ๋ค๋ฅธ ๋ณ์ ๋ฐ์ดํฐ ์ค์ผ, Heap ๋ฉํ๋ฐ์ดํฐ ์์ |
| Double Free | abort() / Segmentation Fault |
| ์ด ์ข์ ๊ฒฝ์ฐ | ์ฐ์ฐํ ์ ์ ๋์์ฒ๋ผ ๋ณด์ โ ๋ ์ํ |
ํต์ฌ: ๋๊ธ๋ง ํฌ์ธํฐ ์ญ์ฐธ์กฐ๋ Undefined Behavior โ ์ปดํ์ผ ์ค๋ฅ๊ฐ ์๊ณ ์ฆ์ ํฌ๋์๋ ์ ๋ ์ ์์ด์ ๋๋ฒ๊น
์ด ๊ฐ์ฅ ์ด๋ ค์ด ๋ฒ๊ทธ ์ ํ.
2. ํฌ์ธํฐ ๋ฉ๋ชจ๋ฆฌ ํฌ๊ธฐ โ 32๋นํธ vs 64๋นํธ
Q: โํฌ์ธํฐ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ช ๋ฐ์ดํธ ์ฐจ์งํ๋์?โ
ํต์ฌ ๋ต๋ณ
ํฌ์ธํฐ์ ํฌ๊ธฐ๋ ๊ณ ์ ์ด ์๋๋๋ค. CPU ์ฃผ์ ๋ฒ์ค ๋๋น(= ํ๋ซํผ์ ๋นํธ ์)์ ๋ฐ๋ผ ๊ฒฐ์ ๋ฉ๋๋ค.
| ํ๋ซํผ | ํฌ์ธํฐ ํฌ๊ธฐ | ์ด์ |
|---|
| 32๋นํธ | 4๋ฐ์ดํธ (32๋นํธ) | ์ฃผ์ ๊ณต๊ฐ 2ยณยฒ = 4GB |
| 64๋นํธ | 8๋ฐ์ดํธ (64๋นํธ) | ์ฃผ์ ๊ณต๊ฐ 2โถโด = 16 EB |
1
2
3
4
5
6
7
8
9
10
| // 64๋นํธ ํ๋ซํผ (ํ๋ PC, ์ฝ์)
sizeof(int*) // 8
sizeof(char*) // 8
sizeof(void*) // 8
sizeof(double*) // 8
// ํฌ์ธํฐ๋ ํ์
(int, char, double)๊ณผ ๋ฌด๊ดํ๊ฒ ๋ชจ๋ ๊ฐ์ ํฌ๊ธฐ
// 32๋นํธ ํ๋ซํผ (์๋ฒ ๋๋, ๊ตฌํ ์์คํ
)
sizeof(int*) // 4
sizeof(void*) // 4
|
์ ํ์
์ ์๊ด์์ด ํฌ๊ธฐ๊ฐ ๊ฐ์๊ฐ?
ํฌ์ธํฐ๊ฐ ์ ์ฅํ๋ ๊ฒ์ โ๊ฐ๋ฆฌํค๋ ๊ฐ์ฒด์ ํ์
์ ๋ณดโ๊ฐ ์๋๋ผ โ๋ฉ๋ชจ๋ฆฌ ์ฃผ์โ์
๋๋ค. ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ ํ๋ซํผ์ ์ฃผ์ ๋ฒ์ค ๋๋น๋ก ๊ณ ์ ๋๋ฏ๋ก, int*๋ double*๋ ์ ์ฅํ๋ ๊ฐ(์ฃผ์)์ ํฌ๊ธฐ๋ ๋์ผํฉ๋๋ค.
1
2
3
4
5
6
7
| int x = 10;
double d = 3.14;
int* pi = &x; // ์ฃผ์ ์ ์ฅ: 8๋ฐ์ดํธ (64๋นํธ)
double* pd = &d; // ์ฃผ์ ์ ์ฅ: 8๋ฐ์ดํธ (64๋นํธ)
// pi์ pd๊ฐ ์ ์ฅํ๋ "์ฃผ์ ๊ฐ"์ ํฌ๊ธฐ๋ ๋์ผ
// ์ฐจ์ด๋ ์ญ์ฐธ์กฐ ์ ์ฝ๋ ๋ฐ์ดํธ ์ (int: 4, double: 8)
|
vptr๋ ํฌ์ธํฐ ํฌ๊ธฐ๋ฅผ ๋ฐ๋ฅธ๋ค
virtual ํจ์๊ฐ ์๋ ํด๋์ค ๊ฐ์ฒด ๋งจ ์์ ์ฝ์
๋๋ vptr๋ ๋์ผํ๊ฒ ํ๋ซํผ ํฌ์ธํฐ ํฌ๊ธฐ๋ฅผ ๋ฐ๋ฆ
๋๋ค.
1
2
3
4
5
6
| class Base {
virtual void Foo() {}
int x;
};
// 64๋นํธ: sizeof(Base) = 8(vptr) + 4(int) + 4(padding) = 16
// 32๋นํธ: sizeof(Base) = 4(vptr) + 4(int) = 8
|
๋ ํผ๋ฐ์ค์ ํฌ๊ธฐ
๋ ํผ๋ฐ์ค ์์ฒด์ ํฌ๊ธฐ๋ฅผ sizeof๋ก ์ธก์ ํ๋ฉด ์๋ณธ ๊ฐ์ฒด์ ํฌ๊ธฐ๊ฐ ๋์ต๋๋ค. ์ปดํ์ผ๋ฌ๊ฐ ๋ ํผ๋ฐ์ค๋ฅผ ๋ด๋ถ์ ์ผ๋ก ํฌ์ธํฐ๋ก ๊ตฌํํ๋๋ผ๋ ์ธ์ด ์์ค์์ ๋๋ฌ๋์ง ์์ต๋๋ค.
1
2
3
4
| int x = 10;
int& r = x;
sizeof(r); // sizeof(int) = 4 โ ํฌ์ธํฐ 8์ด ์๋!
// r์ x์ ๋ณ์นญ์ด๋ฏ๋ก sizeof๊ฐ x์ ํฌ๊ธฐ๋ฅผ ๋ฐํ
|
30์ด ๋ต๋ณ:
ํฌ์ธํฐ ํฌ๊ธฐ๋ ํ๋ซํผ์ ๋นํธ ์์ ๋ฐ๋ผ ๋ค๋ฆ
๋๋ค. 64๋นํธ ์์คํ
์์๋ 8๋ฐ์ดํธ, 32๋นํธ ์์คํ
์์๋ 4๋ฐ์ดํธ์
๋๋ค. ์ด๋ ํฌ์ธํฐ๊ฐ ์ ์ฅํ๋ ๊ฒ์ด ํ์
์ด ์๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์์ด๊ธฐ ๋๋ฌธ์ด๋ฉฐ, ๋ฉ๋ชจ๋ฆฌ ์ฃผ์์ ํฌ๊ธฐ๊ฐ CPU ์ฃผ์ ๋ฒ์ค ๋๋น๋ก ๊ฒฐ์ ๋๊ธฐ ๋๋ฌธ์
๋๋ค.
3. ๋ ํผ๋ฐ์ค์์ ๋ฐํ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์๊น?
Q: โ๋ ํผ๋ฐ์ค๋ ํญ์ ์์ ํ๊ฐ์? ๋ฐํ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์๋์?โ
์งง์ ๋ต๋ณ: ๋ฐ์ํ ์ ์์ต๋๋ค. ๋จ ์ปดํ์ผ ํ์์๋ ์กํ์ง ์์ต๋๋ค.
๋ ํผ๋ฐ์ค๋ ๋ฌธ๋ฒ์ ์ผ๋ก ํญ์ ์ ํจํ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌ์ผ์ผ ํ์ง๋ง, ํ๋ก๊ทธ๋๋จธ๊ฐ ๊ท์น์ ์ด๊ธฐ๋ฉด ๋ฐํ์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
์ผ์ด์ค 1 โ ๋๊ธ๋ง ๋ ํผ๋ฐ์ค (Dangling Reference)
1
2
3
4
5
6
7
| int& GetDangling() {
int local = 42;
return local; // โ ๏ธ ์ปดํ์ผ ๊ฒฝ๊ณ ๋ฐ์
} // local ์๋ฉธ!
int& r = GetDangling();
std::cout << r; // ๐ฅ UB: ์ด๋ฏธ ์๋ฉธ๋ ์คํ ๋ณ์๋ฅผ ๋ ํผ๋ฐ์ค๋ก ์ ๊ทผ
|
์ปดํ์ผ๋ฌ๊ฐ ๊ฒฝ๊ณ ๋ ํ์ง๋ง ์ค๋ฅ๋ ์๋ โ ๋ฐํ์ UB.
์ผ์ด์ค 2 โ nullptr ์ญ์ฐธ์กฐ ํ ๋ ํผ๋ฐ์ค๋ก ๋ณํ
1
2
3
4
5
| int* p = nullptr;
int& r = *p; // ์ปดํ์ผ OK โ ๋ฌธ๋ฒ์ ์ผ๋ก ํ์ฉ
// ์ค์ ์ญ์ฐธ์กฐ๊ฐ ์ผ์ด๋๋ ์์ ์ ๋ฐ๋ผ UB
std::cout << r; // ๐ฅ Segmentation Fault
|
*p๊ฐ null ์ญ์ฐธ์กฐ์ด์ง๋ง ๋ ํผ๋ฐ์ค ๋ฐ์ธ๋ฉ ๋ฌธ๋ฒ์ด ๊ฐ๋ ค์ค๋๋ค.
์ผ์ด์ค 3 โ ์ปจํ
์ด๋ ์ฌํ ๋น ํ ๋ ํผ๋ฐ์ค
1
2
3
4
5
| std::vector<int> v = {1, 2, 3};
int& ref = v[0]; // v ๋ด๋ถ ์์ ๋ ํผ๋ฐ์ค
v.push_back(100); // ์ฌํ ๋น ๋ฐ์ โ ref๊ฐ ํด์ ๋ ๋ฉ๋ชจ๋ฆฌ ์ฐธ์กฐ
std::cout << ref; // ๐ฅ UB: ๋๊ธ๋ง ๋ ํผ๋ฐ์ค
|
ํฌ์ธํฐ์ ์์ ํ ๋์ผํ ๋ฌธ์ โ ๋ ํผ๋ฐ์ค๋ ํผํ ์ ์์ต๋๋ค.
์ผ์ด์ค 4 โ ์๋ช
์ด ๋๋ ์์ ๊ฐ์ฒด ๋ ํผ๋ฐ์ค
1
2
3
4
5
| const int& r = 42; // โ
const ๋ ํผ๋ฐ์ค โ ์์ ๊ฐ์ฒด ์๋ช
์ฐ์ฅ (C++ ๊ท์น)
// r์ ์๋ช
์ด ๋๋ ๋๊น์ง 42 ์ ํจ
int& r2 = someFunc(); // someFunc()์ด int& ๋ฐํ ์
// ๋ฐํ๋ ๋ ํผ๋ฐ์ค๊ฐ ๋ด๋ถ ์ง์ญ๋ณ์๋ฉด ๋๊ธ๋ง!
|
๋ ํผ๋ฐ์ค์ ํฌ์ธํฐ์ ๋ฐํ์ ์ค๋ฅ ๋น๊ต
| ย | ํฌ์ธํฐ | ๋ ํผ๋ฐ์ค |
|---|
| nullptr ๊ฐ๋ฅ | โ
(๋ช
์์ ) | โ (๋ฌธ๋ฒ ๋ถ๊ฐ, ๋จ ์ฐํ ๊ฐ๋ฅ) |
| ๋ฐํ์ ์ค๋ฅ ๊ฐ๋ฅ | โ
| โ
(๋๊ธ๋ง, nullptr ์ฐํ) |
| ์ปดํ์ผ ํ์ ๊ฐ์ง | ์ผ๋ถ | ์ผ๋ถ ๊ฒฝ๊ณ |
| ์ฌํ ๋น ํ ๋ฌดํจํ | โ
| โ
(๋์ผํ๊ฒ ๋ฐ์) |
30์ด ๋ต๋ณ:
๋ ํผ๋ฐ์ค๋ ๋ฐํ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ฃผ์ ์ผ์ด์ค๋ ์ธ ๊ฐ์ง์
๋๋ค. ์ฒซ์งธ, ์ง์ญ ๋ณ์์ ๋ ํผ๋ฐ์ค๋ฅผ ๋ฐํํ๋ฉด ํจ์ ์ข
๋ฃ ํ ๋๊ธ๋ง ๋ ํผ๋ฐ์ค๊ฐ ๋ฉ๋๋ค. ๋์งธ, int& r = *nullptr ๊ฐ์ด null ํฌ์ธํฐ๋ฅผ ์ญ์ฐธ์กฐํด์ ๋ ํผ๋ฐ์ค๋ก ๋ฐ์ธ๋ฉํ๋ฉด UB๊ฐ ๋ฐ์ํฉ๋๋ค. ์
์งธ, vector ์ฌํ ๋น ํ ๊ธฐ์กด ์์ ๋ ํผ๋ฐ์ค๊ฐ ๋ฌดํจํ๋ฉ๋๋ค. ๋ ํผ๋ฐ์ค๊ฐ โํญ์ ์์ ํ๋คโ๋ ๊ฒ์ ๋ฌธ๋ฒ์ ์ ์ฝ์ด์ง, ๋ฐํ์ ์์ ์ ๋ณด์ฅํ์ง๋ ์์ต๋๋ค.
4. ๋๊ธ๋ง ํฌ์ธํฐ ๋ฐฉ์ง ํค์๋ยทํจํด
Q: โ๋๊ธ๋ง ํฌ์ธํฐ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํ ๋ฐฉ๋ฒ์ ๋ฌด์์ธ๊ฐ์?โ
โ delete ํ ์ฆ์ nullptr ์ด๊ธฐํ
1
2
3
4
5
6
7
| int* p = new int(42);
delete p;
p = nullptr; // โ ๋๊ธ๋ง ๋ฐฉ์ง์ ์ต์ ๋ฐฉ์ด์
if (p != nullptr) { // nullptr ์ฒดํฌ๊ฐ ์ด์ ์๋ฏธ ์์ด์ง
*p = 10;
}
|
ํ๊ณ: Double Free๋ ๋ฐฉ์งํ์ง๋ง ์ด๋ฏธ ๊ฐ์ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ค๋ฅธ ํฌ์ธํฐ(alias)๋ ์ฌ์ ํ ๋๊ธ๋ง.
โก unique_ptr โ ์์ ๊ถ ๋จ๋
ํ๋ก Double Free ์์ฒ ์ฐจ๋จ
1
2
3
4
5
6
7
| auto p = std::make_unique<int>(42);
// delete ๋ถํ์ โ ์ค์ฝํ ์ข
๋ฃ ์ ์๋ ํด์
// unique_ptr์ด ์๋ฉธ๋๋ฉด ๋ด๋ถ ํฌ์ธํฐ๋ ์๋ nullptr
// unique_ptr๋ ๋ณต์ฌ ๋ถ๊ฐ โ ๋ ํฌ์ธํฐ๊ฐ ๊ฐ์ ๊ฐ์ฒด ์์ ๋ถ๊ฐ
auto p2 = p; // โ ์ปดํ์ผ ์ค๋ฅ
auto p3 = std::move(p); // โ
์์ ๊ถ ์ด์ , p๋ nullptr
|
โข shared_ptr + weak_ptr โ ์๋ช
์ถ์
1
2
3
4
5
6
7
8
9
| auto shared = std::make_shared<int>(42);
std::weak_ptr<int> weak = shared; // ์์ ๊ถ ์์ด ๊ด์ฐฐ
// ์์ ํ ์ ๊ทผ ํจํด
if (auto locked = weak.lock()) { // shared_ptr ์์ ํ๋
std::cout << *locked; // ์ ํจํ ๊ฒฝ์ฐ์๋ง ์ ๊ทผ
} else {
// ์ด๋ฏธ ํด์ ๋จ
}
|
weak_ptr::lock()์ ์๋ณธ์ด ์ด์์์ผ๋ฉด shared_ptr๋ฅผ ๋ฐํํ๊ณ , ์ด๋ฏธ ํด์ ๋์ผ๋ฉด nullptr๋ฅผ ๋ฐํํฉ๋๋ค. ์์ ํ ๋๊ธ๋ง ๊ฐ์ง ํจํด.
โฃ std::optional โ โ์์ ์๋ ์๋ ๊ฐโ ๋ช
์
1
2
3
4
5
6
7
8
9
10
11
| // ํฌ์ธํฐ ๋์ optional ์ฌ์ฉ โ ๋๊ธ๋ง ์์ฒด๋ฅผ ๊ตฌ์กฐ์ ์ผ๋ก ์ ๊ฑฐ
std::optional<int> Find(const std::vector<int>& v, int target) {
for (int x : v)
if (x == target) return x; // ๊ฐ ๋ฐํ
return std::nullopt; // ์์ ๋ช
์
}
auto result = Find(vec, 42);
if (result.has_value()) {
std::cout << *result; // ์์
}
|
ํฌ์ธํฐ๊ฐ ํ์ํ ์ด์ ๊ฐ โ์์ ์๋ ์์ด์โ๋ผ๋ฉด optional์ด ๋ ์ ํฉํฉ๋๋ค.
โค RAII ํจํด โ ๊ฐ์ฒด ์๋ช
๊ณผ ์์ ์๋ช
๋๊ธฐํ
1
2
3
4
5
6
7
8
9
10
11
12
| // ์๋ชป๋ ํจํด โ ์๋ช
๋ถ์ผ์น
{
int* p = new int(42);
// ... ์์ธ ๋ฐ์ ์ delete ์ ๋จ
delete p; // ๋๋ฌ ๋ชป ํ ์๋ ์์
}
// RAII ํจํด โ ์ค์ฝํ์ ์๋ช
๋๊ธฐํ
{
auto p = std::make_unique<int>(42);
// ์์ธ ๋ฐ์ํด๋ unique_ptr ์๋ฉธ์๊ฐ delete ๋ณด์ฅ
} // ์๋ ํด์
|
โฅ ์ปดํ์ผ๋ฌ ๊ฒฝ๊ณ + Sanitizer
1
2
3
4
5
| # Address Sanitizer โ ๋๊ธ๋ง ํฌ์ธํฐ ์ญ์ฐธ์กฐ๋ฅผ ๋ฐํ์์ ์ฆ์ ๊ฐ์ง
clang++ -fsanitize=address -g main.cpp
# ์ปดํ์ผ๋ฌ ๊ฒฝ๊ณ ํ์ฑํ
g++ -Wall -Wextra -Wnull-dereference
|
1
2
3
4
| # AddressSanitizer ์ถ๋ ฅ ์์
ERROR: AddressSanitizer: heap-use-after-free on address 0x...
READ of size 4 at 0x... thread T0
#0 0x... in main main.cpp:8
|
๋ฐฉ์ง ์ ๋ต ์์ฝ
| ๋ฐฉ๋ฒ | ๋ฐฉ์งํ๋ ์ผ์ด์ค | ๋น์ฉ |
|---|
delete ํ = nullptr | Double Free ๋ฐฉ์ง | ์์ |
unique_ptr | ์์ ๊ถ ๋จ๋
ํ, Double Free | ๊ฑฐ์ ์์ |
shared_ptr + weak_ptr | ์๋ช
๊ณต์ + ๋๊ธ๋ง ๊ฐ์ง | ์ฐธ์กฐ ์นด์ดํ
๋น์ฉ |
std::optional | โ์์ ์๋โ ์ผ์ด์ค | ์์ |
| RAII ํจํด | ์์ธ ๊ฒฝ๋ก ๋์ | ์์ |
| AddressSanitizer | ๋ฐํ์ ๊ฐ์ง (๊ฐ๋ฐ์ฉ) | ์ฑ๋ฅ ์ ํ (ํ๋ก๋์
๋ฏธ์ฌ์ฉ) |
5. ์ธ๋ฆฌ์ผ์์์ ๋๊ธ๋ง ํฌ์ธํฐ
UPROPERTY ์๋ UObject ํฌ์ธํฐ = ๋๊ธ๋ง ์ํ
1
2
3
4
5
6
7
8
9
10
11
| UCLASS()
class AMyActor : public AActor {
GENERATED_BODY()
// โ UPROPERTY ์์ โ GC๊ฐ ์ด ํฌ์ธํฐ๋ฅผ ์ถ์ ํ์ง ์์
UMyComponent* DangerousComp;
// โ
UPROPERTY ์์ โ GC ์ถ์ , ์๊ฑฐ ์ ์ nullptr ์ธํ
UPROPERTY()
UMyComponent* SafeComp;
};
|
GC๊ฐ UMyComponent ์ธ์คํด์ค๋ฅผ ์๊ฑฐํ๋ฉด:
UPROPERTY ์๋ ํฌ์ธํฐ โ GC๊ฐ ์๋์ผ๋ก nullptr ์ธํ
(๋๊ธ๋ง ๋ฐฉ์ง)UPROPERTY ์๋ ํฌ์ธํฐ โ ์๊ฑฐ ํ์๋ ํฌ์ธํฐ ๊ฐ ์ ์ง โ ๋๊ธ๋ง!
IsValid() / IsValidLowLevel()
1
2
3
4
5
6
7
8
9
| // ์ธ๋ฆฌ์ผ์์ UObject ํฌ์ธํฐ ์์ ์ ๊ทผ ํจํด
if (IsValid(SafeComp)) { // nullptr ์ฒดํฌ + ๊ฐ๋น์ง ๋งํน ์ฒดํฌ
SafeComp->DoSomething();
}
// nullptr ์ฒดํฌ๋ง์ผ๋ก๋ ๋ถ์กฑ
if (SafeComp != nullptr) { // โ ๏ธ GC Mark๋์ง๋ง ์์ง ์๊ฑฐ ์ ๋ ๊ฒฝ์ฐ ํต๊ณผ
SafeComp->DoSomething(); // ํฌ๋์ ๊ฐ๋ฅ
}
|
TWeakObjectPtr โ ์ธ๋ฆฌ์ผ์ weak_ptr
1
2
3
4
5
6
7
| TWeakObjectPtr<UMyComponent> WeakComp;
// ์์ ํ ์ ๊ทผ
if (WeakComp.IsValid()) {
UMyComponent* Comp = WeakComp.Get();
Comp->DoSomething();
}
|
GC๊ฐ ๊ฐ์ฒด๋ฅผ ์๊ฑฐํ๋ฉด TWeakObjectPtr๋ ์๋์ผ๋ก invalid ์ํ๊ฐ ๋ฉ๋๋ค. C++ weak_ptr์ ์ธ๋ฆฌ์ผ ๋ฒ์ ์
๋๋ค.
6. ํต์ฌ ์์ฝ ์นด๋
๋๊ธ๋ง ํฌ์ธํฐ 30์ด
1
2
3
4
5
6
7
8
| ๋๊ธ๋ง ํฌ์ธํฐ = ํด์ ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ
3๋ ๋ฐ์ ์์ธ:
1. delete ํ ๋ฏธ์ด๊ธฐํ
2. ์คํ ๋ณ์ ์ฃผ์ ๋ฐํ
3. ์ปจํ
์ด๋ ์ฌํ ๋น ํ ์ดํฐ๋ ์ดํฐ/ํฌ์ธํฐ
๊ฒฐ๊ณผ: UB โ ์ฐ๋ ๊ธฐ ๊ฐ, ๋ฉ๋ชจ๋ฆฌ ์ค์ผ, Double Free, Segfault
๋ฐฉ์ง: delete ํ nullptr / unique_ptr / RAII / AddressSanitizer
|
ํฌ์ธํฐ ํฌ๊ธฐ 30์ด
1
2
3
4
5
6
| ํฌ์ธํฐ ํฌ๊ธฐ = CPU ์ฃผ์ ๋ฒ์ค ๋๋น
32๋นํธ ์์คํ
: 4๋ฐ์ดํธ (์ฃผ์ ๊ณต๊ฐ 4GB)
64๋นํธ ์์คํ
: 8๋ฐ์ดํธ (์ฃผ์ ๊ณต๊ฐ 16EB)
ํ์
(int*, double*)๊ณผ ๋ฌด๊ด โ ์ ์ฅํ๋ ๊ฐ์ด "์ฃผ์"์ด๊ธฐ ๋๋ฌธ
sizeof(๋ ํผ๋ฐ์ค) = ์๋ณธ ๊ฐ์ฒด ํฌ๊ธฐ (ํฌ์ธํฐ ํฌ๊ธฐ ์๋)
|
๋ ํผ๋ฐ์ค ๋ฐํ์ ์ค๋ฅ 30์ด
1
2
3
4
5
6
| ๋ ํผ๋ฐ์ค๋ ๋ฐํ์ ์ค๋ฅ ๋ฐ์ ๊ฐ๋ฅ:
1. ์ง์ญ ๋ณ์ ๋ ํผ๋ฐ์ค ๋ฐํ โ ๋๊ธ๋ง ๋ ํผ๋ฐ์ค
2. int& r = *nullptr โ null ์ญ์ฐธ์กฐ UB
3. vector ์ฌํ ๋น ํ ๊ธฐ์กด ์์ ๋ ํผ๋ฐ์ค โ ๋๊ธ๋ง
"๋ ํผ๋ฐ์ค๋ ํญ์ ์์ " = ๋ฌธ๋ฒ ์ ์ฝ, ๋ฐํ์ ์์ ๋ณด์ฅ ์๋
|
๋๊ธ๋ง ๋ฐฉ์ง ํค์๋
1
2
3
4
5
6
7
| nullptr โ delete ํ ์ฆ์ = nullptr
unique_ptr โ ์์ ๊ถ ๋จ๋
ํ, Double Free ์์ฒ ์ฐจ๋จ
weak_ptr โ ์๋ช
์ถ์ , lock()์ผ๋ก ์์ ์ ๊ทผ
optional โ "์์ ์๋"๋ฅผ ํฌ์ธํฐ ์์ด ํํ
RAII โ ์ค์ฝํ์ ์์ ์๋ช
๋๊ธฐํ
IsValid() โ ์ธ๋ฆฌ์ผ: nullptr + GC ๋งํน ๋์ ์ฒดํฌ
UPROPERTY โ ์ธ๋ฆฌ์ผ: GC ์ถ์ ๋ฑ๋ก (์์ผ๋ฉด ๋๊ธ๋ง)
|
์ฐธ๊ณ