2012-12-07 1 views
0

다음 코드로 C에서 단일 연결 목록의 모든 노드를 삭제하려고합니다. 목록이 비어인지 아닌지 내가 확인하기 위해 그 이후 연결리스트의 모든 요소를 ​​인쇄하면단일 링크 된 목록의 마지막 나머지 노드에서 데이터를 삭제할 수 없습니다.

void free_all(struct cd *head){             
    struct cd *tmp;                                    
    tmp = head->next;               
    while(tmp != NULL){               
     head->next = tmp->next;             
     free(tmp);                
     tmp = head->next;              
    }                   
    free(head->next);               
    free(head);                 
    head=NULL;                 
}   

단, "머리"요소는 항상 인쇄됩니다. 따라서 헤드 요소가 제대로 삭제되지 않는 것 같습니다. 뭐가 문제 야?

답변

4

'head'는 로컬 범위가있는 함수 인수입니다. 따라서 함수의 끝에 NULL을 설정하더라도 함수가 바로 다음에 반환되고 해당 변수를 범위 밖으로 이동하면 아무 효과가 없습니다.

전달 된 변수는 여전히 목록의 헤드를 가리 킵니다 (이 메모리는 해제되었지만 그럴듯한 데이터가 포함되어 있음).

머리 이 해제되었습니다. 당신이 살았던 곳의 메모리를 가리키고 있기 때문에 반드시 그런 식으로 보일 필요는 없습니다.

수정하려면이 기능을 호출하여을 호출 한 후 포인터를 으로 지정하면됩니다.

free_all(actual_head); 
actual_head = NULL; 

포인터 내에서 포인터를 전달할 수 있지만이 상황에서는 지나치게 복잡합니다.

+0

왜 변수가 여전히 목록의 머리를 가리 킵니까? 어떻게 해결할 수 있을까요? – nazco

+0

답변에 약간의 답변을 추가했습니다. 그러나 기본적으로 변수를 변경하지 않았기 때문에 방금 변수를 로컬 복사본으로 변경했습니다. 함수가 반환되면 해당 로컬 복사본은 사라지고 원본은 그대로 유지됩니다. – JasonD

+0

좋아, 이제 네가 의미하는 바를 이해하고 제대로 작동한다. 하지만 내가 머리가 포인터라는 것을 알기 때문에 "참조로 호출"합니다. 이는 참조 만 함수에 주어졌으며 로컬 복사본이 없거나 잘못 되었습니까? – nazco

관련 문제