다음 루틴은 단일 링크 목록 시작시 노드를 제거 할 것으로 예상되지만 때때로 실패합니다.때때로 프로그램이 충돌 함
void remove_from_front(node *start)
{
delete start;
start = start->link;
print_list(start);
}
다음 루틴은 단일 링크 목록 시작시 노드를 제거 할 것으로 예상되지만 때때로 실패합니다.때때로 프로그램이 충돌 함
void remove_from_front(node *start)
{
delete start;
start = start->link;
print_list(start);
}
나는 볼 수
을 당신은 해제 된 메모리에 접근 한 후 start
노드를 확보하고있다. 이것은 잘못된 것이며, 정의되지 않은 동작으로 이어 지므로 어떤 일이 발생할 수 있습니다. 하나의 실행에서는 작동 할 수도 있고 다음 실행에서는 충돌 할 수도 있습니다.
함수가 목록의 머리글을 변경해야하지만 변경된 내용을 반환하지 않으며 인수 start
이 전달됩니다. 이 문제를 해결하려면 start
포인터의 주소 또는 참조를 전달하십시오.
빈 목록에 함수가 호출 될 수 있습니다 (start = NULL
). 그 사건을 처리해야합니다.
올바른 구현 :
void remove_from_front(node **start) {
// if list is empty..nothing to remove..return.
if(*start == NULL) {
return;
}
// save the address of the node following the start in new_start
node *new_start = (*start)->link;
// now delete the start node.
delete *start;
// new_start is now the new start of the list.
// And since start was passed by address, the change is reflected in the
// calling function.
*start = new_start;
}
시작을 삭제 한 다음 링크 멤버를 가져 와서 참조를 취소하려고합니다. 방금 삭제했기 때문에 충돌이 발생합니다.
node *temp = start;
start = start->link;
delete temp;
print_list(start);
링크 부재를 얻을 수있는 역 참조는 아주 아주 가능성이 충돌하는 것입니다. 인쇄가 더 그렇습니다. –
당신 delete start
후에는 안전하게 start
가 가리키는 데 사용 어떤 조각을 사용할 수 없습니다 : 당신은 아마 이런 식으로 뭔가를 할 수 있습니다. 그것은 연 끈을 놓아두고 나중에 다시 잡을 수 있기를 기대하는 것과 같습니다. 효과가있을 수 있습니다. 그렇지 않을 수도 있습니다. 몇 가지 문제가 있습니다
이것은 완전한 대답입니다. +1 – Muggen
+1 좋은 설명 – GWW
항상 코드를 읽기 쉽게하기 위해'node * temp = * start'를 할 수 있습니다. – Muggen