본문 바로가기
컴퓨터/C++과 알고리즘

[C++] map - erase/clear 사용 시 메모리 누수 발생할 경우

by Eisen Frankenstein 2022. 11. 11.

기본 형태 :

map <key, value> myMap;

 

설정 : value 값을 포인터로 주었을 때

          map<int, Player*> m_PlayerMap;

          위의 변수를 클래스의 멤버 변수로 사용

 

예시와 같이 맵을 사용했을 경우, 클래스가 소멸하거나 단순히 clear 만을 사용했을 때는 메모리 누수가 발생한다.

따라서 내부의 포인터로 할당한 변수를 직접 해제해 주는 작업이 필요하다.

 

저런식으로 변수로 사용해놓고 무심결에 해제 작업을 해주지 않는다면, 골치아픈 일이 생길 것이다. 

따라서 어떤 작업을 할때 무언가 생성하는 부분을 만든다면, 동작보다 해제 하는 것부터 작업하는것을 추천한다.

닝겐은 항상 실수를 하기에 작업을 하다가 빼먹을 수 있기 때문이다. 

 

map<int, Player*> m_PlayerMap; -> Monster 클래스에서 멤버변수로 이렇게 설정했다 가정하자.

int main()
{		
	Monster* monster = new Monster();
	
    monster->
    
	delete monster;
	monster = NULL;

	_CrtDumpMemoryLeaks();
	return 0;
}

============================================================================
// 이걸 Monster 클래스 멤버함수라 치고
void TestMethod()
{
    for (int i = 0; i < 5; i++)
    {
        Player* player = new Player();   
        player->data = i + 1;
        SetData(player);       <- 이렇게 동적 할당으로 포인터를 부여했다면
    }		
};

=============================================================================
예시 1번
~Monster() 
{
    cout << "Monster 소멸자 호출" << endl;	
    m_PlayerMap.clear();
};


예시 2번 
~Monster() 
{
    cout << "Monster 소멸자 호출" << endl;			

    map<int, Player*>::iterator itr = m_PlayerMap.begin();
    for (; itr != m_PlayerMap.end(); itr++)
    {
        Player* player = itr->second;
  		delete player;
	}
    m_PlayerMap.clear();
}

예시 1번 처럼 소멸자를 구성하다면 map의 value에 부여되었던 포인터는 해제되지 않는다. (메모리 누수 발생)

예시 2번 처럼 동적할당된 포인터를 해제해주어야한다. (clear는 굳히 시전하지 않아도 된다.)