2026-03-12 TIL (13์ผ์ฐจ)
๐ก [Pro-Tip] C++ ๋ฉ๋ชจ๋ฆฌ ๋์(Memory Leak) ์ก์๋ด๊ธฐ
12์ผ์ฐจ์ ๋ฐฐ์ ๋ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ ์ฝ๊ฒ ์ก์๋ด๋ ์ฝ๋
๋์ ํ ๋น์ด ๋ง์ ๊ฒ์ ๊ฐ๋ฐ์์ ๋ฉ๋ชจ๋ฆฌ ๋์๋ ์น๋ช ์ ์ ๋๋ค. ์๋ ์ฝ๋๋ฅผmainํจ์ ์ต์๋จ์ ๋ฃ์ผ๋ฉด ํ๋ก๊ทธ๋จ ์ข ๋ฃ ์ ์ถ๋ ฅ ์ฐฝ์ ๋์ ์ฌ๋ถ๋ฅผ ์น์ ํ๊ฒ ์๋ ค์ค๋๋ค. ์ ํ์ด ์๋ ํ์์ ๋๋ค!
1 2 3 4 5 6 7 8 9 10 11 #include <crtdbg.h> int main() { // ํ๋ก๊ทธ๋จ ์ข ๋ฃ ์ ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฆฌํฌํธ๋ฅผ ์ถ๋ ฅ์ฐฝ์ ํ์ํจ _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); // ๋ฉ๋ชจ๋ฆฌ ๋ฆญ ์ถ์ . // _CrtSetBreakAlloc(161);//๋๋ฒ๊ทธ์ ์ฐํ ๋ธ๋ญ ๋ฒํธ๋ฅผ ์ ๋ ฅ // ๋ฉ๋ชจ๋ฆฌ ๋ฆญ ์ง์ ์ ์๋์ผ๋ก ์ค๋จ์ ์ ๊ฑธ์ด์ฃผ๋ ํจ์. /* ๋ก์ง ์์ */ }
4๋ฒ๊ณผ์ ํ์๊ธฐ๋ฅ
1. ์ด๋ค ์๋๋ก ์ด ์ฝ๋๋ฅผ ๊ตฌํํ์๊น?
โ AlchemyWorkshopํด๋์ค๊ฐ PotionRecipe๋ฅผ ๊ฐ์ง๊ณ ์์ด์ Has-A๊ด๊ณ
โ PotionRecipeํด๋์ค๋ ๋ฌผ์ฝ ์ด๋ฆ + ์ฌ๋ฌ๊ฐ์ง ์ฌ๋ฃ ๋ชฉ๋ก์ ๋ด๋ ํด๋์ค(๋ฐ์ดํฐ)
โ AlchemyWorkshopํด๋์ค๋ PotionRecipe๋ค์ด ์์ฑ๋๊ฑธ ์ ์ฅํ์ฌ ๊ด๋ฆฌํ๊ณ ์ฌ์ฉํ๋ ํด๋์ค(๋งค๋์ )
2. ์์ ์ ํด์ผ ํ๋ค๋ฉด, ๊ธฐ์กด ์ฝ๋์ ์์ ์ ์ต์ํ ํ ์ ์๋ ๋ฐฉ์์ด ์์๊น?
1) AlchemyWorkshop,PotionRecipe ํ์ผ ๋ถํ
์์ ์ฌํญ
โ ๊ฐ ํด๋์ค ํค๋ํ์ผ์๋ ํด๋์ค ์ ์ธ๋ถ๋ง ๋จ๊ฒจ ์ธํฐํ์ด์ค๋ฅผ ๋ช ํํ ํจ
โ ๊ฐ ํด๋์ค cppํ์ผ์๋ ์ธ๋ถ ๊ตฌํ ๋ก์ง์ ๋ถ๋ฆฌํ์ฌ ์ปดํ์ผ ์๋ ๋ฐ ๊ฐ๋ ์ฑ ํฅ์
2) PotionRecipe ๋ฉค๋ฒ ๋ณ์ ์บก์ํ
PotionRecipe ๋ด ๋ฐ์ดํฐ๊ฐ ์ธ๋ถ์์ ๋ฌด๋ถ๋ณํ๊ฒ ์์ ๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด public ์ ๊ทผ ์ ์ด์๋ฅผ private์ผ๋ก ๋ณ๊ฒฝํ๊ณ ์บก์ํ๋ฅผ ์ ์ฉํ์ต๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
class PotionRecipe {
- public:
- std::string potionName;
- std::vector<std::string> ingredients;
+ private:
+ std::string potionName;
+ std::vector<std::string> ingredients;
+ public:
+ PotionRecipe(const std::string& name, const std::vector<std::string>& ingredients)
+ : potionName(name), ingredients(ingredients) {
+ }
};
๋ฉค๋ฒ ๋ณ์๋ฅผ private๋ก ์ ์ธ์ ํ๊ธฐ๋๋ฌธ์ ๋ค๋ฅธ ๊ณณ์์ ์ ๊ทผ์ ๋ชปํ๊ธฐ ๋๋ฌธ์ ์ค๋ฅ๊ฐ ์๊ฒจ ๋ฉค๋ฒ ํจ์ get์ผ๋ก ๊ฐ์ ๋ฐ์์ค๊ฒ ๊ตฌํ
3. ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ผ๋ฉด SOLID ์์น์ ์ ์ค์ํ๊ณ ์๋?
1) SRP (๋จ์ผ ์ฑ
์ ์์น) PotionRecipe: ๋ ์ํผ ๋ฐ์ดํฐ ์ ๋ณด๋ง ์ ๋ฌธ์ ์ผ๋ก ๋ด์ต๋๋ค.
AlchemyWorkshop: ๋ ์ํผ๋ค์ ๋ชฉ๋ก์ ๊ด๋ฆฌํ๋ ๋ก์ง์๋ง ์ง์คํฉ๋๋ค.
2) OCP (๊ฐ๋ฐฉ-ํ์ ์์น) ์ ๊ฒ ๋ฐ ํด๊ฒฐ
๋ฌธ์ ์
๋ง์ฝ PotionRecipe์ gold, time ๊ฐ์ ์๋ก์ด ๋ณ์๊ฐ ์ถ๊ฐ๋๋ค๋ฉด?
โ addRecipe ํจ์์ ๋งค๊ฐ๋ณ์๋ฅผ ๋งค๋ฒ ๋ฏ์ด๊ณ ์ณ์ผ ํฉ๋๋ค.
โ ํด๋น ํจ์๋ฅผ ํธ์ถํ๋ ํ๋ก์ ํธ ๋ด์ ๋ชจ๋ ์ฝ๋์์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉฐ ์ผ์ผ์ด ์์ ํด์ผ ํฉ๋๋ค.
1
2
3
4
// AlchemyWorkshop.h
- void addRecipe(string name, vector<string> ingredients);
+ // ์์ฑ๋ ๊ฐ์ฒด ์์ฒด๋ฅผ ๋๊ฒจ์ค์ผ๋ก์จ ํ์ฅ์ ์ ์ฐํ๊ฒ ๋์ฒ
+ void addRecipe(const PotionRecipe& newRecipe);
ํด๊ฒฐ ๊ฒฐ๊ณผ
โ ์ ์ง๋ณด์์ฑ ํฅ์: PotionRecipe ํด๋์ค์ ์ด๋ค ๋ณ์๊ฐ ์ถ๊ฐ๋๋๋ผ๋ AlchemyWorkshop์ ์ฝ๋๋ ๋จ ํ ์ค๋ ์์ ํ ํ์๊ฐ ์์ต๋๋ค.
โ ์ฝ๋ ์์ ์ฑ: ์ ์ ์ ์ ๋ ฅ์ ๋ฐ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ main ํจ์ ์ฝ๋๋ง ์์ ํ๋ฉด ๋๋ฏ๋ก, ๊ธฐ์กด ๋งค๋์ ํด๋์ค์ ๋ก์ง์ ๊ฑด๋๋ฆด ์ํ์ด ์ฌ๋ผ์ง๋๋ค.
4.๋ฌผ์ฝ ์ด๋ฆ์ผ๋ก ๊ฒ์์ด ๊ฐ๋ฅํ๊ฒ ํ๊ธฐ
๋ฌผ์ฝ์ ์ด๋ฆ์ผ๋ก ๋ ์ํผ๋ฅผ ์ฐพ๋ ๊ฒ์ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ฉด์, ๋ฐํํ์ ๊ธฐ์กด์ PotionRecipe (๊ฐ ๋ฐํ)์์ PotionRecipe* (ํฌ์ธํฐ ๋ฐํ)๋ก ๋ณ๊ฒฝํ์ต๋๋ค.
1
2
3
4
// AlchemyWorkshop.h
- PotionRecipe FindRecipe(const std::string& name);
+ // ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์์ ๊ฒฝ์ฐ๋ฅผ ๋๋นํ์ฌ ํฌ์ธํฐ๋ก ๋ณ๊ฒฝ
+ PotionRecipe* FindRecipe(const std::string& name);
๐ก ํฌ์ธํฐ๋ก ๋ฐํํ๋ ์ด์
- ์์ธ ์ฒ๋ฆฌ์ ๋ช ํ์ฑ (nullptr ํ์ฉ)
โ ๊ธฐ์กด ๋ฐฉ์: ๋ฌผ์ฝ์ ์ฐพ์ง ๋ชปํ์ ๋ โ๋น์ด์๋ ๊ฐ์ง ๊ฐ์ฒดโ๋ฅผ ์ต์ง๋ก ์์ฑํด์ ๋ฐํํด์ผ ํ์ต๋๋ค. ์ด๋ ๋ถํ์ํ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๊ณผ ๋ณต์กํ ์ฒดํฌ ๋ก์ง์ ์ผ๊ธฐํฉ๋๋ค.
โ ๊ฐ์ ๋ฐฉ์: ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์์ผ๋ฉด ๊ฐ๋จํ nullptr์ ๋ฐํํ๋ฉด ๋ฉ๋๋ค. ํธ์ถํ๋ ์ชฝ์์๋ if (ptr == nullptr) ํ ์ค๋ก ๊น๋ํ๊ฒ ์์ธ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
- ์ฑ๋ฅ ์ต์ ํ (Copy Overhead ์ ๊ฑฐ)
โ ๊ธฐ์กด ๋ฐฉ์: PotionRecipe ๊ฐ์ฒด ๋ด๋ถ์ ๋ง์ ์ฌ๋ฃ ๋ฐ์ดํฐ(std::vector ๋ฑ)๊ฐ ๋ด๊ฒจ ์์ ๊ฒฝ์ฐ, ๊ฐ์ ๋ณต์ฌํด์ ๋๊ฒจ์ฃผ๋ ๊ณผ์ ์์ ์๋นํ ์ฑ๋ฅ ์ ํ๊ฐ ๋ฐ์ํฉ๋๋ค.
โ ๊ฐ์ ๋ฐฉ์: ๊ฐ์ฒด์ ํฌ๊ธฐ์ ์๊ด์์ด ๋จ 8๋ฐ์ดํธ(64๋นํธ ๊ธฐ์ค)์ ์ฃผ์๊ฐ๋ง ์ฃผ๊ณ ๋ฐ์ผ๋ฏ๋ก ์ฐ์ฐ ์๋๊ฐ ๋น์ฝ์ ์ผ๋ก ํฅ์๋ฉ๋๋ค.
C++ ๊ฐ์
1.์์ฑ์
โ ํด๋์ค๋ฅผ ์๋ฃํ์ผ๋ก ํฌ์ธํฐ๋ฅผ ์ ์ธํ๊ณ ํ ๋น์ ์๋ฐ๊ณ ๊ทธ๋ฅ ์ ์ธ๋ง ํ๋ฉด ์์ฑ์๋ ํธ์ถ์๋๋ค.
(์ฃผ์๊ฐ๋ง ์ ์ฅํ๋ค๊ณ ํ๋๊ฑฐ์ง ๊ฐ์ฒด๊ฐ ๋ง๋ค์ด์ง๋๊ฑฐ๋ ์๋๋ค.)
โ ๋ฉค๋ฒ๋ณ์๋ก const๋ ์ฐธ์กฐ์๊ฐ ์์ ๋ ์์ฑํ์๋ง์ ๊ฐ์ด ์ด๊ธฐํ๋ฅผ ์์ผ์ค์ผํ๊ธฐ๋๋ฌธ์ ์ด๋์ ๋ผ์ด์ฆ๋ก ๋ฌด์กฐ๊ฑด ์ด๊ธฐํ ์์ผ์ค์ผํ๋ค.
โ ์์ฑ์๊ฐ ์ ์๋์ด ์๋๋ฐ ํด๋์ค๋ฅผ ๋ฐฐ์ด๋ก ๋ฐ๊ณ ์ถ์๋
(๋ํดํธ ์์ฑ์๋ฅผ ๋ง๋ค๋ฉด ๋์ง๋ง ๋ชป๋ง๋ค ๊ฒฝ์ฐ)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//1๋ฒ ๋ฐฉ๋ฒ
//์์ฑ์๊ฐ ์ ์ธ๋ ํด๋์ค๋ฅผ ๋ฐฐ์ด๋ก ์ ์ธํ๋ ๋ฐฉ๋ฒ
int a = 10;
// 20๊ฐ๋ฅผ ๋ค ์ ๊ธฐ ํ๋ค์ง๋ง, ์ด๋ ๊ฒ ํ๋ฉด ๊ธฐ๋ณธ ์์ฑ์ ์์ด ๋ฐฐ์ด ์ ์ธ์ด ๊ฐ๋ฅํฉ๋๋ค.
Test A[3] = { Test(a), Test(a), Test(a) };
//2๋ฒ ๋ฐฉ๋ฒ
// ์ฃผ์๊ฐ(ํฌ์ธํฐ) 20๊ฐ๋ฅผ ๋ด์ ๊ณต๊ฐ์ ๋ง๋ญ๋๋ค. (์ด๋๋ Test์ ์์ฑ์๊ฐ ํ์ ์์ต๋๋ค.)
Test** arr = new Test * [20];
// ๋ฐ๋ณต๋ฌธ์ ๋๋ฉฐ ๋ด๊ฐ ์ํ๋ ๊ฐ(a)์ ๋ฃ์ด ์ง์ง ๊ฐ์ฒด๋ค์ ํ๋์ฉ ์์ฑํฉ๋๋ค.
for (int i = 0; i < 20; ++i)
{
arr[i] = new Test(a); // ์์ฑ์ ํธ์ถ ์ฑ๊ณต!
}
//3๋ฒ ๋ฐฉ๋ฒ(์ ์ผ ์ฝ๊ณ ๋ง์ด ์)
int a = 10;
// 20๊ฐ์ ์นธ์ ๋ง๋ค๊ณ , ๋ชจ๋ ์นธ์ Test(a) ๊ฐ์ฒด๋ก ๋ณต์ฌํด์ ์ฑ์๋๋ค.
std::vector<Test> v(20, Test(a));
