Nếu biến số temp
có thể được sử dụng lại sau này, thì tốt nhất là đặt giá trị NULL.
Có hai lý do bạn thường đặt con trỏ thành NULL sau khi phát hành nó.
1.) Khi bạn nhả con trỏ, bộ nhớ tại địa chỉ được trỏ đến không còn có sẵn cho chương trình của bạn nữa. Về mặt lý thuyết, bộ nhớ đó hiện có thể được sử dụng bởi bất kỳ chương trình nào khác, kể cả hệ điều hành! Cố gắng để phát hành một con trỏ đã được phát hành và do đó chỉ ra những người biết những gì có thể gây ra một vấn đề lớn. Các hệ điều hành hiện đại may mắn bảo vệ chống lại điều này nhưng chương trình vẫn sẽ bị lỗi với một lỗi truy cập bất hợp pháp. Phát hành một con trỏ null OTOH sẽ làm hoàn toàn không có gì.
2.) Bạn nên luôn luôn kiểm tra xem con trỏ không phải là NULL trước khi tham chiếu nó với toán tử *
. De-tham chiếu một con trỏ NULL sẽ gây ra một lỗi thời gian chạy. De-tham chiếu một con trỏ được phát hành trỏ đến một số bộ nhớ tùy ý thậm chí còn tồi tệ hơn. Một con trỏ được giải phóng phải luôn được đặt thành NULL
để mã sau có thể giả định một điểm con trỏ không null tới dữ liệu hợp lệ. Nếu không thì không có cách nào để biết liệu con trỏ có còn hợp lệ hay không.
Đối với câu hỏi ban đầu, biến con trỏ temp
được khai báo dưới dạng biến cục bộ trong một hàm ngắn mà ở đó không bao giờ được sử dụng lại. Trong trường hợp này, nó không cần thiết để đặt nó thành NULL vì nó nằm ngoài phạm vi ngay sau khi hàm trả về.
Tuy nhiên, dòng ...
(*head)->next = (*head)->next->next;
thất bại trong việc đảm bảo (*head)->next
không phải là null trước khi cố gắng bỏ tham khảo, một không-không.
Một phiên bản tốt hơn sẽ là ...
int DeleteAfter(Node **head){
Node *node_after = NULL;
if(*head==NULL)
return -1;
node_after = (*head)->next;
if(node_after == NULL)
return -1;
(*head)->next = node_after->next;
delete node_after;
return 0;
}
Lúc này người sử dụng chức năng có thể kiểm tra xem việc xóa nút đã thành công bởi giá trị trả về và không có nguy cơ cố gắng để xóa một không tồn tại nút.
Không. Chỉ cần sử dụng một con trỏ thông minh. – chris
ở đây nó là hoàn toàn không thích hợp cho dù bạn đặt nó vào NULL hay không. 'temp' là một biến với lưu trữ tự động, có nghĩa là nó sẽ nằm ngoài phạm vi sau khi thoát khỏi khối' else'. nhưng như @chris nói, chỉ cần sử dụng con trỏ thông minh –
cũng, thực tế là '* head' không phải là' NULL' không có nghĩa là '(* head) -> next' không phải là' NULL', và bạn đang cố gắng dereference con trỏ đó ('(* đầu) -> tiếp theo -> ...') –