Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ 프로그래밍으로 연결 리스트 전체를 삭제하는 함수 작성 방법

이번 글에서는 연결 리스트(Linked List)의 모든 노드를 하나씩 순회하며 삭제하는 함수를 만들어 보겠습니다.

C/C++에는 이 작업을 한 번에 처리해 주는 내장 함수가 없습니다. 반면 Java에서는 자동 가비지 컬렉션(Garbage Collection)이 지원되기 때문에 사용되지 않는 객체가 자동으로 메모리에서 해제됩니다. 하지만 C++에서는 개발자가 직접 메모리를 관리해야 하므로, 연결 리스트를 삭제하는 로직을 직접 구현해야 합니다.

연결 리스트 삭제의 핵심 원리

연결 리스트를 안전하게 삭제하려면 다음 순서를 따라야 합니다.

1. 현재 노드의 다음 노드 주소를 미리 저장합니다.
2. 현재 노드의 데이터를 출력하거나 필요한 작업을 수행합니다.
3. free() 또는 delete로 현재 노드의 메모리를 해제합니다.
4. 저장해 둔 다음 노드로 포인터를 이동합니다.
5. 모든 노드가 해제되면 헤드 포인터를 NULL로 설정하여 댕글링 포인터(Dangling Pointer)를 방지합니다.

만약 다음 노드의 주소를 저장하지 않고 먼저 메모리를 해제하면, 그 다음 노드에 접근할 수 없게 되어 나머지 노드들이 메모리 누수(Memory Leak)의 원인이 됩니다.

예제 코드

#include <iostream>
using namespace std;

class Node {
public:
    int data;
    Node* next;
};

// 연결 리스트의 모든 노드를 삭제하는 함수
void deleteLinkedList(Node** head_ref) {
    Node* current = *head_ref;
    Node* next;

    while (current != NULL) {
        cout << current->data << "\t";  // 삭제 전 데이터 출력
        next = current->next;           // 다음 노드 주소 백업
        free(current);                  // 현재 노드 메모리 해제
        current = next;                 // 다음 노드로 이동
    }
    *head_ref = NULL;                   // 헤드 포인터 초기화
}

// 리스트 앞쪽에 새 노드를 추가하는 함수
void push(Node** head_ref, int new_data) {
    Node* new_node = new Node();
    new_node->data = new_data;
    new_node->next = (*head_ref);
    (*head_ref) = new_node;
}

int main() {
    Node* head = NULL;

    push(&head, 25);
    push(&head, 10);
    push(&head, 5);
    push(&head, 90);
    push(&head, 68);

    cout << "연결 리스트의 요소 : ";
    deleteLinkedList(&head);
    cout << "\n연결 리스트가 삭제되었습니다.";

    return 0;
}

실행 결과

연결 리스트의 요소 : 68 90 5 10 25
연결 리스트가 삭제되었습니다.

코드 설명

push() 함수는 새 노드를 리스트의 맨 앞에 삽입하므로, 마지막에 추가한 값이 가장 먼저 출력됩니다. 따라서 25, 10, 5, 90, 68 순서로 삽입한 데이터가 역순인 68, 90, 5, 10, 25로 출력됩니다.

deleteLinkedList() 함수는 이중 포인터(Node**)를 매개변수로 받아, 삭제가 완료된 후 호출부의 헤드 포인터까지 NULL로 갱신할 수 있습니다. 이렇게 하면 이미 해제된 메모리를 가리키는 댕글링 포인터 문제를 예방할 수 있습니다.

C++에서는 free() 대신 delete 연산자를 사용하는 것이 권장되며, 실무에서는 스마트 포인터(std::unique_ptr, std::shared_ptr)나 STL 컨테이너(std::list, std::forward_list)를 활용하면 수동 메모리 관리 없이도 안전하게 연결 리스트를 사용할 수 있습니다.