미해결
[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part1: C++ 프로그래밍 입문
안녕하세요! virtual 소멸자에 대해서 질문드려요!
안녕하세요. 좋은 강의 항상 감사드립니다. 덕분에 C# 부터 시작해서 C++까지 즐겁게 배우고 있는 중입니다. :)
다름이 아니라 질문드리고 싶은건 상위 클래스 소멸자에 virtual을 붙이지 않았을 때 메모리 Leak이 발생하는 지 테스트를 진행했는데 crtdbg를 사용해서 메모리 누수 체크를 해보니 누수된 메모리가 나오지 않았습니다.그래서 성능 프로파일러에서 힙 프로파일링 옵션을 켠 뒤에 두 상황에 대해서 아래의 사진과 같이 비교를 해봤을 때 동일한 결과가 나왔습니다. 이 상황에서 메모리 누수가 발생하지 않는 것인지못찾아내고 있는 것인지 궁금합니다!
#include <iostream>
#include <iomanip>
#include <crtdbg.h>
#if _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#define malloc_d(s) _malloc_dbg(s, _NORMAL_BLOCK,__FILE__,__LINE__)
#endif
using namespace std;
class Item
{
public:
Item()
{
cout << "Item()" << endl;
}
Item(const Item& item)
{
cout << "Item(const Item& item)" << endl;
}
Item(int itemType)
{
cout << "Item(int itemType)" << endl;
_itemType = itemType;
}
// 상위 개념에는 virtual을 붙여야 함
~Item()
{
cout << "~Item()" << endl;
}
public:
int _itemType = 0;
int _itemDbId = 0;
char _dummy[4096] = {}; // 이런 저런 정보들로 인해 비대해진 데이터라 가정
};
enum ItemType
{
IT_WEAPON = 1,
IT_ARMOR = 2,
};
class Weapon : public Item
{
public:
Weapon() : Item(IT_WEAPON)
{
cout << "Weapon()" << endl;
_attack = rand() % 1000;
}
~Weapon()
{
cout << "~Weapon()" << endl;
}
public:
int _attack = 0;
};
class Armor : public Item
{
public:
Armor() : Item(IT_ARMOR)
{
cout << "Armor()" << endl;
}
~Armor()
{
cout << "~Armor()" << endl;
}
public:
int _defence = 0;
};
int main()
{
// 1번 스냅샷
Item* inventory[20] = {};
srand(time(nullptr));
for (int i = 0; i < 20; i++)
{
int randValue = rand() % 2; // 0~1
switch (randValue)
{
case 0:
inventory[i] = new Weapon();
break;
case 1:
inventory[i] = new Armor();
break;
}
}
for (int i = 0; i < 20; i++)
{
Item* item = inventory[i];
// 포인터 사용할 때는 항상 null 체크 필수
if (item == nullptr)
continue;
if (item->_itemType == IT_WEAPON)
{
Weapon* weapon = (Weapon*)item;
cout << "Weapon Damage : " << weapon->_attack << endl;
}
}
// 2번 스냅샷
for (int i = 0; i < 20; i++)
{
Item* item = inventory[i];
if (item == nullptr)
continue;
delete item;
}
// crt 메모리 체크 : 메모리 Leak이 발생할 시 출력창에 표기 됨
_CrtDumpMemoryLeaks();
// 3번 스냅샷
return 0;
}
virtual을 사용한 경우
virtual을 사용하지 않은 경우