ã¬ã¬ã·ãŒç¬¬18ç« ïŒèªäœã¡ã¢ãªãªãŒã¯æ€ç¥åšãšã¯ã©ãã·ã¥ãã³ãè§£æ
ã°ããŒãã« new/delete ãªãŒããŒã©ã€ãã«ãã確ä¿å±¥æŽãã©ããã³ã°ãšã³ãŒã«ã¹ã¿ãã¯èšé²
ãã²ãŒã çµäºæã«32ãã€ãã ãã¡ã¢ãªãªãŒã¯ããŠãããšèŠåãåºãããæ°åäžè¡ã®ã©ãã§ç¢ºä¿ãããã®ãèŠåœãã€ããªãããæ¬çªç°å¢ã®ãã¬ã€ã€ãŒã®PCã§ã ãã10æéã«1åè¬ã®ã¯ã©ãã·ã¥ãçºçãããââçãã€ã³ã¿ãæå管çããã¬ã¬ã·ãŒC++éçºã«ãããŠãæãããã°ã©ãã®ç²Ÿç¥ãåãã®ãã¡ã¢ãªç Žå£ãšãªãŒã¯ã§ããValgrindãAddressSanitizerã䜿ããªãçµèŸŒã¿æ©åšãç¬èªã²ãŒã æ©ç°å¢ã§ã¯ãèªåãã¡ã§ã¡ã¢ãªè¿œè·¡ã·ã¹ãã ãéçºããã®ãçŸå Žã®åžžèã§ãããæ¬ç« ã§ã¯ãã°ããŒãã« operator new / delete ããªãŒããŒã©ã€ãããç¢ºä¿æã®ãã¡ã€ã«åã»è¡çªå·ã»ãã€ãæ°ãåæ¹åãªã³ã¯ãªã¹ãã§èšé²ãããèªäœã¡ã¢ãªãªãŒã¯æ€ç¥ã·ã¹ãã ããæ§ç¯ããŸãã
L18.1 ã32ãã€ããæ¶ããïŒãã¬ã¬ã·ãŒçŸå Žã襲ãã¡ã¢ãªãªãŒã¯ã®æªå€¢
ãªãã²ãŒã ã§1ãã€ãã®ã¡ã¢ãªãªãŒã¯ãèš±ãããªãã®ãïŒ é·æé皌åã§çºçããã¡ã¢ãªæ¯æžã®ææãè§£åããŸãã
ð§ ãã³ã®ã³å
茩
ã·ãã¯ãå
çãã²ãŒã ãçµäºãããšãã«ãããã¬ã®ãã°ã«ãDetected memory leaks! 32 bytesããšäžè¡ã ã衚瀺ããããã§ãããã£ã32ãã€ãããããã²ãŒã ãåèµ·åãããOSãååããŠããããç¡èŠããŠããã§ãããâŠïŒ
ð»ââïž ã·ãã¯ãå
ç
倧åãããŒãŒãŒã£ïŒïŒã²ãŒã æ©ãçµèŸŒã¿æ©åšããããŠäœåæéãæŸçœ®ãããMMOãã¹ããã²ãŒã ã«ãããŠããæ¯ãã¬ãŒã 32ãã€ãæŒããããã°ããã£ããã©ããªããšæãã®ããïŒïŒ
ð§ ãã³ã®ã³å
茩
1ãã¬ãŒã ïŒ1/60ç§ïŒã§32ãã€ãã ãšâŠ1ç§ã§çŽ2KBã1åã§çŽ120KBã1æéã§çŽ7.2MBâŠæ°æéãã¬ã€ãããã¹ããã®ã¡ã¢ãªãé£ãå°œãããŠåŒ·å¶çµäºïŒOOMã¯ã©ãã·ã¥ïŒããŸããâŠïŒ
ð»ââïž ã·ãã¯ãå
ç
ãã®éãïŒãªãŒã¯ã®æå€§ã®åé¡ã¯ãäœäžè¡ãããã³ãŒãã®ãã©ã® new ãè§£æŸãããŠããªãã®ãåãããªããããšãããã©ãã§ new ããããè¡çªå·ãšãã¡ã€ã«åãçªãæ¢ããä»çµã¿ããèªåã§ãšã³ãžã³ã«çµã¿èŸŒãã®ããïŒ
ð¡ ãã®ã»ã¯ã·ã§ã³ã®éèŠãã€ã³ã
- ãŒããªãŒã¯ã®éå: å®¶åºçšã²ãŒã æ©ãã¹ããã²ãŒã ã§ã¯ãé·æéã®é£ç¶çšŒåã«èãããã1ãã€ãã®ã¡ã¢ãªãªãŒã¯ã蚱容ãããªãã
- 確ä¿ã³ã³ããã¹ãã®ä¿å: ã¢ãã¬ã¹ãšãµã€ãºã ãã§ãªãããã¡ã€ã«åã»è¡çªå·ã®ã¡ã¿ããŒã¿ã確ä¿ãããã«çŽä»ããããšã§ãããã°ãåçã«å®¹æã«ãªãã
L18.2 ã°ããŒãã« operator new / delete ã®ãªãŒããŒããŒãè¡
C++ã®æãæ·±ãéè¡ã®1ã€ãèšèªæšæºã®ã¡ã¢ãªã¢ãã±ãŒã¿ãããã¯ããå
šç¢ºä¿ãååãããã¯ããã¯ã
ð§ ãã³ã®ã³å
茩
new æŒç®åã£ãŠãC++ã®èšèªä»æ§ãã®ãã®ã§ãããïŒããã°ã©ããäžèº«ãåæã«æžãæããŠããŸã£ãŠããããã§ããïŒ
ð»ââïž ã·ãã¯ãå
ç
ããã®ããïŒC++èšèªä»æ§ã§ã¯ãã°ããŒãã« operator newããããã°ã©ããç¬èªå®çŸ©ïŒãªãã¬ãŒã¹ïŒããããšãæ£åŒã«èªããããŠãããããã䜿ã£ãŠãã¹ãŠã® new / delete ãæã
ã®ç£èŠäžã«çœ®ãã®ããïŒ
### ãnewãåŒ ãš ãoperator newãã®æ±ºå®çãªéã
C++åå¿è
æå€§ã®æ··ä¹±ãã€ã³ããããã§ãïŒ
1. **ãnewãåŒïŒèšèªä»æ§ã»æ§æïŒ**:
Enemy* e = new Enemy();
ããã¯ã³ã³ãã€ã©ã«ãã£ãŠä»¥äžã®2段éã®åŠçã«å€æãããŸãïŒ
- ã¹ãããA: void* mem = operator new(sizeof(Enemy)); ïŒã¡ã¢ãªç¢ºä¿é¢æ°ïŒ
- ã¹ãããB: Enemy::Enemy() ããã®ã¡ã¢ãªäžã§å®è¡ïŒã³ã³ã¹ãã©ã¯ã¿åŒã³åºãïŒ
2. **ãoperator newãïŒãã ã®é¢æ°ïŒ**:
ã¡ã¢ãªã®çãã€ãé åã確ä¿ããŠè¿ãã ãã®é¢æ°ïŒmalloc ã«è¿ãïŒã
**æã
ããªãŒããŒããŒãã§ããã®ã¯ããã®ã¹ãããAã®é¢æ°ãªã®ã§ãïŒ**
ð MemoryTracker.hpp
#ifndef MEMORY_TRACKER_HPP
#define MEMORY_TRACKER_HPP
#include <cstdlib>
#include <iostream>
// 確ä¿ãããã¡ã¢ãªãããã¯ã®å
é ã«ä»äžããã¡ã¿ããŒã¿
struct MemoryHeader {
size_t size;
const char* filename;
int line;
MemoryHeader* next;
MemoryHeader* prev;
};
// ã°ããŒãã«ãªãªã³ã¯ãªã¹ãå
é
extern MemoryHeader* g_allocatedHead;
extern size_t g_totalAllocatedBytes;
// ãããã°çš operator newïŒãã¡ã€ã«åãšè¡çªå·ãåãåãïŒ
void* operator new(size_t size, const char* filename, int line);
void* operator new[](size_t size, const char* filename, int line);
// éåžžã® delete
void operator delete(void* ptr) throw();
void operator delete[](void* ptr) throw();
// ãããã°ãã«ãæã®ã¿ new ã眮æãããã¯ã
#if defined(_DEBUG) || !defined(NDEBUG)
#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW
#endif
// ãªãŒã¯ã¬ããŒãåºå颿°
void dumpMemoryLeaks();
#endif
ð¡ ãã®ã»ã¯ã·ã§ã³ã®éèŠãã€ã³ã
- newåŒãšoperator newã®æç¢ºãªåºå¥: newåŒã¯ã¡ã¢ãªç¢ºä¿ïŒã³ã³ã¹ãã©ã¯ã¿å®è¡ããªãŒããŒã©ã€ãã§ããã®ã¯ã¡ã¢ãªç¢ºä¿é¢æ°ã§ãã operator newã
- ããããŒãã¬ãã£ãã¯ã¹ææ³: 確ä¿èŠæ±ãµã€ãºããå°ã倧ããªé åãåããå
é ã«ã¡ã¿ããŒã¿ãæ ŒçŽããŠãã€ã³ã¿ãããããŠè¿ãã®ãã¢ãã±ãŒã¿ã®å®ç³ã
L18.3 åæ¹åãªã³ã¯ãªã¹ãã«ãã確ä¿ããããšçµäºæãªãŒã¯ã¬ããŒã
確ä¿ãããå
šãããã¯ãéã§ç¹ããdeleteããããå€ããçãæ®ã£ããããã¯ãã²ãŒã çµäºæã«åçºããå®å
šå®è£
ã
ð§ ãã³ã®ã³å
茩
ãªãã»ã©ïŒnew ãããããªã¹ãã«è¿œå ããŠãdelete ãããããªã¹ãããé€å€ããã°ãã²ãŒã çµäºæã«ãªã¹ãã«æ®ã£ãŠãããã®ïŒã¡ã¢ãªãªãŒã¯ã§ããïŒ
ð»ââïž ã·ãã¯ãå
ç
ãã®éãããïŒãã ããã©ãã«ãŒèªèº«ã®ãªã¹ã管çã« std::vector ã std::map ã䜿ããšããã©ãã«ãŒå
éšã§ new ãåŒã°ããŠç¡éååž°ïŒãããããã¯ïŒããŠããŸããçã®ãã€ã³ã¿ã䜿ã£ãåæ¹åãªã³ã¯ãªã¹ãã§èªäœããã®ãéåããïŒ
ð MemoryTrackerDemo.cpp
#include <iostream>
#include <cstdlib>
struct MemoryBlock {
size_t size;
const char* file;
int line;
MemoryBlock* next;
};
static MemoryBlock* g_head = NULL;
void* my_alloc(size_t size, const char* file, int line) {
// ããããŒåäœèšã«ç¢ºä¿
size_t total = sizeof(MemoryBlock) + size;
MemoryBlock* blk = (MemoryBlock*)std::malloc(total);
blk->size = size;
blk->file = file;
blk->line = line;
blk->next = g_head;
g_head = blk;
// ããŒã¿é åãžã®ãã€ã³ã¿ãè¿ã
return (void*)(blk + 1);
}
void my_free(void* ptr) {
if (!ptr) return;
MemoryBlock* target = ((MemoryBlock*)ptr) - 1;
// ãªã¹ãããé€å€ïŒç°¡æå®è£
ïŒ
if (g_head == target) {
g_head = target->next;
} else {
MemoryBlock* curr = g_head;
while (curr && curr->next != target) {
curr = curr->next;
}
if (curr) curr->next = target->next;
}
std::free(target);
}
void reportLeaks() {
std::cout << "
=== Memory Leak Report ===" << std::endl;
int count = 0;
MemoryBlock* curr = g_head;
while (curr) {
std::cout << "[LEAK] File: " << curr->file
<< ", Line: " << curr->line
<< ", Size: " << curr->size << " bytes" << std::endl;
count++;
curr = curr->next;
}
if (count == 0) {
std::cout << "âš Perfect! 0 bytes leaked." << std::endl;
} else {
std::cout << "â Total " << count << " leak(s) found!" << std::endl;
}
}
int main() {
// æ£åžžãªç¢ºä¿ãšè§£æŸ
int* p1 = (int*)my_alloc(sizeof(int) * 10, "main.cpp", 57);
my_free(p1);
// æå³çãªè§£æŸå¿ãïŒãªãŒã¯çºçïŒïŒ
char* leak1 = (char*)my_alloc(64, "Player.cpp", 108);
double* leak2 = (double*)my_alloc(sizeof(double) * 2, "Enemy.cpp", 215);
// ããã°ã©ã çµäºæã«ãªãŒã¯äžèЧãåºå
reportLeaks();
// åŸçä»ã
my_free(leak1);
my_free(leak2);
return 0;
}
ð¡ ãã®ã»ã¯ã·ã§ã³ã®éèŠãã€ã³ã
- èªå·±åç
§ã¢ãã±ãŒã·ã§ã³ã®åé¿: ã¡ã¢ãªã¢ãã±ãŒã¿èªèº«ãåçã¡ã¢ãªãèŠæ±ãããšç¡éã«ãŒãã«é¥ããããåºå®é·ããããèªåãªã³ã¯ãªã¹ãã§å®çµãããã
- ç¶ç¶çã€ã³ãã°ã¬ãŒã·ã§ã³ïŒCIïŒãžã®çµã¿èŸŒã¿: èªåãã¹ãçµäºæã«ãªãŒã¯æ€ç¥åšã0ä»¶ã§ããããšãã¢ãµãŒãããããšã§ãã¡ã¢ãªãªãŒã¯ã®ãã¹ã¿ãŒãã©ã³ãæ··å
¥ãæªç¶ã«é²ãã
L18.4 ã¯ã©ãã·ã¥ãã³ãè§£æãšçŸå Žã®ã·ã³ãã«è§£æ±º
ãã¬ã€ã€ãŒã®æå
ã§èµ·ããã¯ã©ãã·ã¥ãé éãããã°ãããMiniDumpãšPDBã·ã³ãã«ãã¡ã€ã«ã®çŸå Žå®åã
ð§ ãã³ã®ã³å
茩
éçºç°å¢ã§ã¯äžåèµ·ããªãã®ã«ãã²ãŒã ãå
¬éããåŸã«ãŠãŒã¶ãŒããããããã¹ãåããç¬éã«åŒ·å¶çµäºããããšå ±åãæ¥ãŸãããåçŸã§ããªããŠé ãæ±ããŠããŸãâŠ
ð»ââïž ã·ãã¯ãå
ç
ããã§æŽ»èºããã®ããã¯ã©ãã·ã¥ãã³ãïŒMiniDump / Core DumpïŒãããïŒã¯ã©ãã·ã¥ããç¬éã®CPUã¬ãžã¹ã¿ãšã¹ã¿ãã¯ã¡ã¢ãªããã¡ã€ã«ã«æžãåºããéçºè
ã®æå
ã§ãã®ç¬éã®å€æ°ã®å€ãã³ãŒã«ã¹ã¿ãã¯ãäžžããšã¿ã€ã ãã©ãã«åçŸããã®ããïŒ
ð¡ ãã®ã»ã¯ã·ã§ã³ã®éèŠãã€ã³ã
- PDBã·ã³ãã«ãã¡ã€ã«ã®å³éä¿ç®¡: ãªãªãŒã¹ãã«ãã®ãã€ããªãšå®å
šã«äžèŽãããããã°ã·ã³ãã«ïŒPDBãã¡ã€ã«ïŒããªããã°ããã³ããã¡ã€ã«ãããœãŒã¹ã³ãŒãè¡ã埩å
ã§ããªãã
ð ç解床ãã§ãã¯ã¯ã€ãº
Q1. C++ã® new åŒïŒEnemy* e = new Enemy();ïŒã«ãããŠãããã°ã©ããç¬èªã«ãªãŒããŒããŒãã§ããã®ã¯ã©ã®éšåã§ããïŒ
- 1. ã³ã³ã¹ãã©ã¯ã¿ã®å®è¡ã¿ã€ãã³ã°ã®ã¿
- 2. ã¡ã¢ãªé åã®çãã€ãã確ä¿ãã颿° operator new(size_t) ã®ã¿
- 3. C++ã³ã³ãã€ã©ã®åå¥è§£æãã§ãŒãºã®ã¿
- 4. CPUã®L1ãã£ãã·ã¥å¶åŸ¡åœä»€ã®ã¿
æ£è§£ãšè§£èª¬ãèŠã
æ£è§£ïŒã¡ã¢ãªé åã®çãã€ãã確ä¿ãã颿° operator new(size_t) ã®ã¿
new åŒã¯ãoperator new ã«ããã¡ã¢ãªç¢ºä¿ããšãã³ã³ã¹ãã©ã¯ã¿åŒã³åºããã®2段éã§æ§æãããããã°ã©ãããªãŒããŒããŒãã§ããã®ã¯åè
ã® operator new 颿°ã§ãã
Q2. ã¡ã¢ãªãªãŒã¯æ€ç¥åšã«ãããŠãå確ä¿ãããã¯ã®ãã¡ã€ã«åãšè¡çªå·ãç¹å®ããããã«åºã䜿ãããããªããã»ããµãã¯ãã¯ã©ãã§ããïŒ
- 1. #define new new(__FILE__, __LINE__)
- 2. #define delete exit(0)
- 3. #define malloc free
- 4. #pragma once
æ£è§£ãšè§£èª¬ãèŠã
æ£è§£ïŒ#define new new(__FILE__, __LINE__)
__FILE__ ãš __LINE__ ã¯ã³ã³ãã€ã«æã«çŸåšã®ãœãŒã¹ãã¡ã€ã«åãšè¡çªå·ã«çœ®æãããå®çŸ©æžã¿ãã¯ãã§ããããããã operator new ã®è¿œå åŒæ°ãšããŠæž¡ãããšã§ç¢ºä¿å
ãèšé²ã§ããŸãã
Q3. èªäœã¡ã¢ãªã¢ãã±ãŒã¿ããªãŒã¯ãã©ãã«ãŒã®å®è£
å
ã§ãstd::vector ã std::map ãªã©ã®åçSTLã³ã³ããã®äœ¿çšãé¿ããã¹ãæå€§ã®çç±ã¯äœã§ããïŒ
- 1. STLã䜿ããšC++ã®ã©ã€ã»ã³ã¹æãçºçãããã
- 2. STLå
éšã§ new ãåŒã°ãããã©ãã«ãŒèªèº«ãèªåèªèº«ãåŒã³åºããŠç¡éååž°ããããããã¯ã«é¥ãå±éºããããã
- 3. STLã䜿ããšç»é¢ã®è§£å床ãäœäžãããã
- 4. std::vector ã¯Cèšèªã§ã³ã³ãã€ã«ã§ããªããã
æ£è§£ãšè§£èª¬ãèŠã
æ£è§£ïŒSTLå
éšã§ new ãåŒã°ãããã©ãã«ãŒèªèº«ãèªåèªèº«ãåŒã³åºããŠç¡éååž°ããããããã¯ã«é¥ãå±éºããããã
ã«ã¹ã¿ã ã¢ãã±ãŒã¿å
ã§æšæºSTLã³ã³ããã䜿ããšããã®ã³ã³ãããããã«ã¡ã¢ãªãèŠæ±ã㊠operator new ãåŒã³åºããç¡éååž°ã¯ã©ãã·ã¥ãåŒãèµ·ãããŸãã
Q4. ãªãªãŒã¹ç°å¢ã§çºçããã¯ã©ãã·ã¥ãã³ãããããœãŒã¹ã³ãŒãã®ãã¡ã€ã«åãè¡çªå·ãæ£ç¢ºã«åŸ©å
ããããã«äžå¯æ¬ ãªãã¡ã€ã«ã¯äœã§ããïŒ
- 1. ã²ãŒã ã®BGMãµãŠã³ããã¡ã€ã«ïŒ.wavïŒ
- 2. ãã«ãæã«çæããããããã°ã·ã³ãã«ãã¡ã€ã«ïŒWindowsã§ã¯.pdbãLinuxã§ã¯.symçïŒ
- 3. ã²ãŒã ã®README.txtãã¡ã€ã«
- 4. GPUã®ãã£ã¹ãã¬ã€ãã©ã€ãã€ã³ã¹ããŒã©
æ£è§£ãšè§£èª¬ãèŠã
æ£è§£ïŒãã«ãæã«çæããããããã°ã·ã³ãã«ãã¡ã€ã«ïŒWindowsã§ã¯.pdbãLinuxã§ã¯.symçïŒ
ã·ã³ãã«ãã¡ã€ã«ïŒ.pdbïŒã«ã¯æ©æ¢°èªã®ã¢ãã¬ã¹ãšãœãŒã¹ã³ãŒãã®ãã¡ã€ã«åã»è¡çªå·ã»å€æ°åã®å¯Ÿå¿é¢ä¿ãèšé²ãããŠãããã¯ã©ãã·ã¥ãã³ãè§£æã«å¿
é ã§ãã
ð»ââïž ã·ãã¯ãC++ã©ã ã€ã³ã¿ã©ã¯ãã£ãåŠç¿ã·ã¹ãã
ãã©ãŠã¶ã§JavaScriptãæå¹ã«ãããšããã©ãŠã¶å
ã€ã³ããŒããŒã²ãŒã ãšãã¥ã¬ãŒã¿ãã¡ã¢ãªãããå¯èŠåãUMLã¯ã©ã¹å³ã察話å解説ãç解床ã¯ã€ãºãèµ·åããŸãã
ã€ã³ã¿ã©ã¯ãã£ãåŠç¿ãéå§ãã â