리스트 노드해제

조회수 689회

클래스와 구조체를 이용해서 리스트를 흉내 봤는데요 노드를 해제할때 밑에 있는 코드만 있으면 힙영역에 있는것들이 모두 해제 되나요?

일단 코드의 일부만 복사 했는데 이 코드들로만 판단이 안되면 다시 올릴게요 (class CIntList에 노드의 시작주소와 데이터값을 저장하는 변수를 2개 선언했어요, 그리고 구조체 노드에는 다음 노드의 주소와 데이터값을 저장하는 변수를 2개 선언했어요)

    ~tNode()
    {
        if (NULL != pNext)
        {
            delete pNext;
        }

    }



CIntList::~CIntList() 
{
    if (NULL != m_pHead)
    {    
        delete m_pHead;
    }
}

1 답변

  • 좋아요

    0

    싫어요
    채택 취소하기

    단일 연결 리스트를 말씀하시는 건가요? 현재 아마 작은 단위의 데이터는 상관없이 모두 해제될 겁니다.

    1) 이렇게 아래처럼 적어주시고 디버깅하시면 디버깅 창 아웃풋에 memory leak이 있는지 알려줍니다. 혹시 모르니 본인 코드로 직접 해보세요.

    #define _CRTDBG_MAP_ALLOC
    
    // 다른 헤더 파일 위, 아래에 넣어줍니다
    #include <iostream>
    using std::cout;
    
    #include <stdlib.h>
    #include <crtdbg.h>
    
    int main()
    {
        // 메인 함수 가장 위에 넣어줍니다.
        _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );  
        // ...
        return 0;
    }
    

    2) 자 근데, 지금 코드도 잘되는데 이 아래에 있는 길고 쓸데없어 보이는 코드는 뭔가요? 문제는 위에 '작은 단위의 데이터'라고 했듯이 지금 코드가 능률적이지 않고 불안정하다는 점에 있습니다.

    지금 코드는 list 오브젝트가 해제되기 위해, 그 소멸자에서 노드 head 포인터를 삭제합니다. 그럼 그 노드는 소멸자를 부르고, 그 다음 노드를 삭제하는데 그러기 위해서 그 다음 노드의 소멸자를 부르고 그 다음 다음 노드를 지울려고 그 다음 다음 노드의 소멸자를 부르고...

    여기서 문제는 가장 마지막 노드의 소멸자가 불려질 때 그 전 모든 노드의 소멸자 함수가 아직 열려있기 때문입니다. 소멸자는 스택 메모리를 사용하는데 모든 노드가 삭제될 때까지 메모리 사용은 늘어가기만 하고 줄어들지를 않습니다. 1000개 정도 크기의 데이터에서는 상관없겠지만, 그 크기가 10000, 100000개를 넘어가면 스택 메모리가 부족해서 에러가 날겁니다.

    이걸 고치기 위해서 이런 재귀적 (반복적) 호출 방식을 피해, 각 노드를 리스트에서 직접 지워줍시다.

    CIntList::~CIntList()
    {
        tNode * trail_node = nullptr;
        tNode * travel_node = m_pHead;
    
        while(travel_node != nullptr)
        {
            // 현재 travel_node (head 혹은 다음 노드)를 지우기 위해
            // 복사본을 만들어줍니다.
            trail_node = travel_node;
            // 복사 후에 다음 노드로 넘어갑니다.
            travel_node = travel_node->m_pNext;
            // 아까 복사한걸 지워줍니다.
            delete trail_node;
        }
    
        // 값의 초기화
        m_pHead = nullptr;
    }
    

    이제 노드 소멸자에서는 다음 노드의 소멸자를 불러 삭제 delete 할 필요가 없습니다.

    tNode::~tNode()
    {
        // 값의 초기화
        m_pNext = nullptr;
        m_data = 0;
    }
    
    
    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)