Post

2026-03-12 TIL (13์ผ์ฐจ)

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);

๐Ÿ’ก ํฌ์ธํ„ฐ๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ด์œ 

  1. ์˜ˆ์™ธ ์ฒ˜๋ฆฌ์˜ ๋ช…ํ™•์„ฑ (nullptr ํ™œ์šฉ)
    โ— ๊ธฐ์กด ๋ฐฉ์‹: ๋ฌผ์•ฝ์„ ์ฐพ์ง€ ๋ชปํ–ˆ์„ ๋•Œ โ€œ๋น„์–ด์žˆ๋Š” ๊ฐ€์งœ ๊ฐ์ฒดโ€๋ฅผ ์–ต์ง€๋กœ ์ƒ์„ฑํ•ด์„œ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ถˆํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๊ณผ ๋ณต์žกํ•œ ์ฒดํฌ ๋กœ์ง์„ ์•ผ๊ธฐํ•ฉ๋‹ˆ๋‹ค.
    โ— ๊ฐœ์„  ๋ฐฉ์‹: ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ์—†์œผ๋ฉด ๊ฐ„๋‹จํžˆ nullptr์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ํ˜ธ์ถœํ•˜๋Š” ์ชฝ์—์„œ๋„ if (ptr == nullptr) ํ•œ ์ค„๋กœ ๊น”๋”ํ•˜๊ฒŒ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  1. ์„ฑ๋Šฅ ์ตœ์ ํ™” (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));
This post is licensed under CC BY 4.0 by the author.