if (node == NULL)
return NULL;
struct NODE* n = node;
while (n != NULL)
{
struct NODE* m = n->next;
if (m->data == data)
{
n->next = m->next;
free(m);
break;
}
n = n->next;
}
답을 이런식으로 구해 출력은 제대로 되지만 처음엔 다음과 같이 짰습니다.
if (node == NULL)
return NULL;
struct NODE* n = node;
while (n != NULL)
{
if ((n->next)->data == data)
{
n->next = (n->next)->next;
free(n->next);
break;
}
n = n->next;
}
단지 n->next를 풀어 쓴 것 뿐인데 왜 위에는 정상작동하고 밑에는 정상작동하지 않는지 이유를 모르겠습니다. n->next가 다음 노드의 포인터를 반환하는것 아닌가요?
코드 보고 머리로 이해하려 하지 말고 해당 단원의 연결 리스크 그림을 참고해서 그림으로 그려서 이해하세요.
그림으로 세세하게 단계별로 나눠서 그리면 뭘 잘못했는지 명확하게 알 수 있습니다. 알고리즘은 세세하게 문서화 작업하고, 그림을 그려서 이해하고, 코딩은 마지막 단계에 하면 됩니다. 실제로 알고리즘은 생각이 90%, 코드 작성은 10%의 과정입니다.
head -> a -> b -> c
이렇게 이러지는 노드가 있다고 합시다.
현재 n = a입니다.
n->next는 b이고
n->next->next는 c입니다.
(n->next)->data = data라는 것은 현재 n=a인데 b 노드에서 data가 있음을 확인했다는 뜻입니다.
n->next = (n->next)->next는
a = c로 지정했다는 뜻입니다. n은 a이고, n->next는 b인데, (n->next)->next는 c이니 n->next는 이제 c를 가리키게 됩니다.
이제 n->next는 b가 아니라 c를 가리키게 됩니다.
free(n->next)
free에서는 n->next를 해제하는 데, 이는 b가 아니라 c를 해제하게 됩니다.
b는 어디론가 사라졌습니다.
포럼 상단의 코드 비주얼라이저 사이트에서 코드를 실행해보면 됩니다. scanf는 삭제하고 다음과 같이 데이터를 미리 정해줍니다.
54 | int numArr[10] = { 1,2,3,4,5,6,7,8,9, 0 }; |
55 | int removeNum = 5; |
물론, 이 코드는 5가 있는 NODE는 삭제했지만, 메모리를 해제할 방법이 없으니까 메모리 누수는 발생하는 상황입니다. 역시나 잘못된 코드.
이제 free(n->next)를 합시다.
4가 있는 NODE 하나만 날렸지만, 그 뒤에 있는 NODE에 접근할 방법도 사라졌습니다. 역시나 해당 노드는 메모리를 해제하지 않았으니까 메모리 누수가 발생합니다.
next 포인터에는 쓰레기 값이 들어가고, 똥 코드가 됩니다.
UNIT 6 디버거 사용법을 참고해서 중단점을 설정하고 Visual Studio에서 실행해도 다음과 같은 상태임을 알 수 있습니다.
디버거 사용은 프로그래머의 필수 스킬이니 꼭 익혀야 합니다.
변수 curr, prev, 두 개를 사용해야 합니다.
한 개의 변수로 모든 것을 처리한다는 것은 불가능성에 도전하는 것으로 보입니다.
a -> b -> c가 있을 때 변수 하나로 a -> c로 바꾸는 것은 가능하지만,
메모리를 해제하려면 b를 가리키는 포인터가 하나는 반드시 필요합니다.
a -> c로 바꾼 상태에서 a->next를 free하면 c를 날리게 되고, c 이후의 모든 노드를 삭제하는 결과가 됩니다.
b를 가리키는 변수가 하나도 없는 상황에서 b를 해제할 방법은 없습니다. 이를 메모리 누수라고 합니다.
아아.. 그래서 비쥬얼스튜디오에서 실행시키면 100 90 80 70 60 50까지 잘 가다가 40 이후의 노드를 날려버리니 메모리참조에러가 나타났던 거군요 말씀하신대로 코딩이 어떻게 동작하는지 그림으로 구상하여 살펴봤다면 금방 찾았을 문제를 그저 코드만 보고 문제를 찾으려고 했네요... 댓글 달아주신걸 보다보면 좀 창피하네요 앞으론 이해안가는 것들도 최대한 그림으로 그려서 문제를 풀어보려고 하겠습니다 자세한 답변 정말 감사드립니다