본문 바로가기

자료구조&알고리즘

[단일 연결 리스트] 문자열 노드 전체 제거

단일 연결 리스트에서 모든 문자열 노드를 제거하는 방법에 대해 알아보도록 하자. 

기존에 int나 double 같은 데이터가 포함된 노드를 제거할 때는 단순히 노드 자체만 제거하면 끝났다. 하지만 문자열이 포함된 노드를 제거할 때는 상황이 다르다. 예를 들어, "apple"이나 "strawberry"와 같은 문자열은 malloc을 통해 동적 할당된 메모리이다.

 

 

 

따라서, 문자열 연결 리스트의 노드를 제거할 때는 다음과 같은 두 가지 작업을 모두 수행해야 한다. 

  1. 문자열에 할당된 동적 메모리 해제
  2. 노드 자체의 메모리 해제

여기서 중요한 점은 노드를 제거하기 전에 반드시 문자열의 메모리를 먼저 해제해야 한다는 것이다. 만약 노드를 먼저 제거하면 문자열의 주소를 가리키던 포인터가 사라져서 문자열의 메모리를 해제할 방법이 없어진다.

즉, "apple"이라는 문자열의 메모리를 해제하려면, 먼저 str이 가리키는 메모리를 해제한 후에 노드를 제거해야 한다.

이제 전체 문자열 노드를 제거하는 방법을 단계별로 알아보자. 

 

  1. 첫 번째 노드를 제거한다. 이를 위해 delNode를 사용하여 제거할 노드를 가리킨다. 이때, 첫 번째 노드가 제거할 노드가 된다.
  2. head를 두 번째 노드를 가리키도록 설정한다.
  3. delNode가 가리키는 첫 번째 노드의 문자열 메모리를 해제한다.
  4. 그 다음, delNode의 메모리를 해제한다.
  5. head가 가리키는 곳으로 delNode를 업데이트한다.
  6. 위 과정을 반복하여 모든 노드를 제거한다.

이 방법을 반복하면 연결 리스트의 모든 문자열 노드를 안전하게 제거할 수 있다.

 

마지막으로, 포인터를 free 할 때, 포인터 자체가 제거되는 것이 아니라 포인터가 가리키는 메모리가 제거된다는 점을 이해하는 것이 중요하다. 

 

예를 들어, delNode가 가리키는 str, 즉 free(delNode->str)를 하면, str 포인터가 제거되는 것이 아니라 str이 가리키는 문자열 "apple"이 제거된다. 

 

마찬가지로 free(delNode)는 delNode 포인터가 제거되는 것이 아니라 delNode가 가리키는 메모리가 제거된다. 

typedef struct node {
    char* str;
    struct node* next;
} node;

node* head = NULL; // 연결 리스트의 전역 head 포인터

void removeStringNodeAll() {
    node* delNode;
    if (head == NULL) return;

    // 첫 노드를 반복해서 제거
    while (head != NULL) {
        delNode = head;
        head = head->next;
        free(delNode->str); // 문자열 메모리 해제 (str이 가리키는 값)
        free(delNode); // 노드 메모리 해제 (delNode 가 가리키는 str 메모리)
    }
}