我純粹出于學習目的使用原始指標/不安全的 Rust 創建鏈表。我注意到一些我無法理解的東西。
struct Node{
data : i32,
next : * mut Node,
}
struct MyFirstUnsafeQueue{
head : * mut Node,
tail : * mut Node,
}
impl MyFirstUnsafeQueue{
fn new()->Self{
return MyFirstUnsafeQueue { head: std::ptr::null_mut(), tail: std::ptr::null_mut() };
}
/**
* Adds an element at the rear of the queue
*/
fn push_1(& mut self, element:i32){
let mut new_node = Box::into_raw(Box::new(Node{
data :element,
next : std::ptr::null_mut(),
}));
if self.head.is_null(){
//https://doc.rust-lang.org/std/primitive.pointer.html#common-ways-to-create-raw-pointers
self.head = new_node;
self.tail = new_node;
}else{
unsafe{
(*self.tail).next = new_node;
self.tail = new_node;
}
}
}
fn push_2(& mut self, element:i32){
let mut new_node = Box::new(Node{
data :element,
next : std::ptr::null_mut(),
});
if self.head.is_null(){
//https://doc.rust-lang.org/std/primitive.pointer.html#common-ways-to-create-raw-pointers
self.head = & mut * new_node;
self.tail = & mut * new_node;
}else{
unsafe{
(*self.tail).next = & mut *new_node;
self.tail = & mut * new_node;
}
}
}
}
#[test]
fn test_push_1(){
unsafe{
let mut q:MyFirstUnsafeQueue = MyFirstUnsafeQueue::new();
q.push_1(1);
assert_eq!(1, (*q.head).data);
assert_eq!(1, (*q.tail).data);
q.push_1(2);
assert_eq!(1, (*q.head).data);
assert_eq!(2, (*q.tail).data);
}
}
#[test]
fn test_push_2(){
unsafe{
let mut q:MyFirstUnsafeQueue = MyFirstUnsafeQueue::new();
q.push_2(1);
assert_eq!(1, (*q.head).data);
assert_eq!(1, (*q.tail).data);
q.push_2(2);
assert_eq!(1, (*q.head).data);
assert_eq!(2, (*q.tail).data);
}
}
test_push_2 失敗并顯示以下錯誤訊息。但是,當我除錯它時,它通過了。
thread 'hello_unsafe::unsafe_queue_02::test_push_2' panicked at 'assertion failed: `(left == right)`
left: `1`,
right: `2`', src/hello_unsafe/unsafe_queue_02.rs:74:9
我正在使用 Visual Studio 代碼 Mac OS。test_push_1 沒有問題。我無法弄清楚為什么會這樣。
uj5u.com熱心網友回復:
您的測驗 usingpush_2表現出未定義的行為,即 use-after-free,因為new_node在每次呼叫結束時都會被銷毀,這將釋放內容。再次呼叫時,headandtail指標懸空.push_2()。
您的測驗push_1有效,因為Box::into_raw將其Box轉換為原始指標并且不會釋放它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/530132.html
標籤:指针锈生的
上一篇:使用指標以相反的順序列印陣列元素
