목차
메모리 해제 시, next 는 해제하지 않는 이유는?
next 에는 다음 노드 주소값이 저장되어 있는데, 이를 해제하면 다음 노드 메모리를 해제하는 결과가 발생하기 때문이다.
예시로 다음과 같이 2개의 노드가 연결되어 있다고 해보자.
node1 의 content 를 삭제하고, node1 의 메모리를 해제 하고 싶다면, 먼저content 가 가리키고 있는 “hello” 가 점유하고 있는 메모리 공간을 삭제하는 함수 del 를 사용한다.
그 다음 포인터 변수인 node1 가 가리키고 있는 주소값을 free 한다.
만약 next 까지 해제한다면 다음과 같은 모습일 것이다.
이렇게 해제를 하면 다음 노드인 node2 의 메모리 공간이 해제되고, 해제된 공간에 다른 값이 저장되어 node2 가 가지고 있던 값이 예측할 수 없는 값으로 변경될 위험이 있다. 그렇기 때문에 next 는 메모리 해제를 하면 안된다.
노드 삭제 후 끊어진 노드들은 이어주어야 하는가?
삭제하고자 하는 노드가 첫 번째 노드나 마지막 노드가 아닌 중간에 있는 노드일 때, 중간 노드 앞뒤에 있는 노드들은 이어주어야 할까?
일반적인 연결리스트를 구현하고자 한다면, 이어주는 것이 맞다. 하지만, ft_lstdelone 함수의 프로토타입에는 매개변수로 삭제하고자 하는 노드에 대한 포인터만 전달된다. 즉, 이전 노드의 주소를 알 수 없으므로 다음 노드와 이어주고 싶어도 주어진ft_lstdelone 함수 내부에서는 이어줄 수 없는 것이다.
ft_lstdelone 함수에서 이전 노드와 다음 노드를 이어줄 수 있는 방법은 삭제하는 노드의 이전 노드 주소를 매개변수에 추가로 전달하는 방법이 있다. 그렇다면 함수는 다음과 같은 형태가 될 것이다.
void ft_lstdelone(t_list prev, t_list target, void(*del)(*));
C
복사
또는, ft_lstdelone 함수 외부에서 삭제할 노드의 이전 노드 주소를 임시 변수에 저장하는 방법도 있다. 이는 ft_lstdelone 함수를 어떻게 활용하느냐에 따라 다르게 구현할 수 있을 것이다.
삭제한 노드를 가리키는 포인터는 NULL 로 변경해야 하는가?
변경할 필요 없다. 함수 내부로 전달되는 단일 포인터 값을lst = NULL 로 변경한다 해도 함수 외부의 lst 값이 변경되지 않기 때문이다. 이는 연결리스트에서 이중 포인터를 사용하는 이유와 비슷한 맥락에서 이해할 수 있다.
•
참고자료 : 연결리스트에서 이중 포인터를 전달하는 이유는?
예를 들어, 다음과 같은 코드가 있다고 하자.
#include "libft.h"
void del(void *content) // 구현 생략
{
...
}
void ft_lstdelone(t_list *lst, void (*del)(void *))
{
...
}
int main(void)
{
t_list *node;
char *str = ft_strdup("hello");
node = ft_lstnew(str);
ft_lstdelone(node, del);
return (0);
}
C
복사
main 함수에서 node 의 값과 주소는 다음과 같다.
(t_list *) node = 0x0000000100205ca0
(t_list **) &node = 0x00007ffeefbff7f8
C
복사
다음으로 ft_lstdelone 함수에서 lst 의 값과 주소는 다음과 같다.
(t_list *) lst = 0x0000000100205ca0
(t_list **) &lst = 0x00007ffeefbff7d8
C
복사
값을 간단하게 이해하기 쉽게 표현하면 다음과 같다.
이때, ft_lstdelone 함수 내부에서 lst 에 NULL 값을 넣으면 어떻게 바뀔까?
lst = NULL 을 수행하고 나서 ft_lstdelone 에서 확인한 lst 의 값과 주소값은 다음과 같다.
(t_list *) lst = 0x0000000000000000
(t_list **) &lst = 0x00007ffeefbff7d8
C
복사
main 함수에서 확인한 node 의 값과 주소값은 다음과 같다.
(t_list *) node = 0x0000000100404090
(t_list **) &node = 0x00007ffeefbff800
C
복사
즉, main 함수에서는 node 의 값이 변경되지 않았음을 알 수 있다. 표로 표현하면 다음과 같다.