Câu hỏi của tôi:con trỏ và bộ nhớ động phân bổ
int* x = new int;
cout << x<<"\n";
int* p;
cout << p <<"\n";
p = x;
delete p;
cout << p <<"\n";
tôi đã viết này hoàn toàn bằng bản thân mình để hiểu được con trỏ và hiểu (hay còn bị lạc trong) năng động new
và delete
.
My XCode có thể biên dịch chương trình và trả về kết quả như sau:
0x100104250
0x0
0x100104250
Tôi biết tôi chỉ có thể gọi xóa trên bộ nhớ cấp phát động. Tuy nhiên, tôi gọi là xóa trên p
trong chương trình ở trên và nó biên dịch.
Có ai có thể giải thích điều này cho tôi không? Tại sao tôi có thể xóa p
?
Hơn nữa, tôi thấy nếu chương trình thay đổi như sau:
int* x = new int;
int* p;
cout << p <<"\n";
delete p;
cout << p <<"\n";
Sau đó Xcode của tôi một lần nữa biên dịch và trả về tôi:.
0x0
0x0
Program ended with exit code: 0
và bây giờ, tôi đã hoàn toàn mất :( Có ai vui lòng giải thích cho tôi điều này không? Tại sao tôi có thể xóa p
vì nó không có gì với x
?
Vì Xcode biên dịch thành công, tôi cho rằng hai chương trình trên là chính xác cho máy tính. Tuy nhiên, tôi nghĩ rằng đó là một lần nữa tuyên bố của "chỉ gọi xóa trên bộ nhớ phân bổ động". Hoặc có lẽ, tôi không hoàn toàn hiểu con trỏ là gì và bộ nhớ được cấp phát động là gì. Tôi tìm thấy số này post khi tôi tìm kiếm trực tuyến. Nhưng tôi không nghĩ nó giống như trường hợp của tôi.
Hãy giúp tôi.
Tôi muốn hỏi một câu hỏi nữa. Mã số là here về cây tìm kiếm nhị phân. Từ dòng 28 đến 32, nó đề cập đến việc xóa một nút với một đứa trẻ. Tôi đặt phần mã này ở đây, trong trường hợp liên kết web không hoạt động.
else nếu (root-> left == NULL) { struct Node * temp = root; root = root-> right; xóa tạm thời; }
Đây là những mã dẫn tôi hỏi câu hỏi trên liên quan đến con trỏ. Theo sau câu trả lời được đưa ra bởi bài đăng này. Có đúng để hiểu mã theo cách sau không?
Tôi không thể liên kết trước tiên nút gốc của gốc từ gốc đến đúng con gốc. và sau đó xóa nút gốc, vì cây con bên dưới nút gốc cũng sẽ bị xóa. Vì vậy, tôi phải tạo ra một con trỏ tạm thời, trỏ đến khe cắm bộ nhớ, được trỏ đến bởi root. Sau đó, tôi liên kết nút cha của gốc để con phải của root. và bây giờ, tôi có thể xóa an toàn khe cắm bộ nhớ được chỉ bằng "gốc", (tức là tạm thời khi cả hai đều trỏ đến cùng một bộ nhớ). Bằng cách này, tôi giải phóng bộ nhớ và giữ liên kết giữa cha mẹ và con cái. Ngoài ra, temp vẫn còn ở đó và vẫn trỏ đến khe nhớ "đó". Tôi có nên đặt thành NULL sau khi xóa không?
Cảm ơn bạn trước một lần nữa.
Yaofeng
Bạn "may mắn" là 'p' là' 0' trong mẫu mã thứ hai của bạn. Vì nó chưa được khởi tạo, nó có thể có bất kỳ giá trị nào. Vì nó là '0' (hay còn gọi là' NULL'), nó có giá trị để gọi 'delete' (điều này rất hữu ích để tránh có một triệu kiểm tra cho' NULL', đặc biệt là khi xử lý các điều kiện lỗi khi phân bổ không thành công, và bạn muốn dọn dẹp phần còn lại của phân bổ - nếu tất cả các con trỏ được khởi tạo thành 'NULL' trước, thì bạn có thể chỉ' xóa' mọi thứ, mà không lo lắng cái nào không được cấp phát). –
Chỉ là một lời khuyên, bạn nên khởi tạo biến con trỏ của bạn như int * p = 0; hoặc int * p = NULL; Đó là bởi vì trong quá trình xây dựng gỡ lỗi, điều này sẽ được thực hiện cho bạn. Nhưng trong bản phát hành, nó sẽ không được thực hiện. Điều này có thể giúp bạn tiết kiệm rất nhiều thời gian gỡ lỗi. – user743414
@ user743414 Trừ khi bạn đang duy trì mã cũ, bạn nên sử dụng C++ 11 và do đó 'int * p = nullptr;'. (Phần này) C++ 11 đã được hỗ trợ bởi tất cả các trình biên dịch chính trong nhiều năm nay. – Angew