List 如何在这个简单的双链表实现中修复SIGSEGV?

List 如何在这个简单的双链表实现中修复SIGSEGV?,list,pointers,linked-list,rust,unsafe,List,Pointers,Linked List,Rust,Unsafe,运行此代码时,我收到一个SIGSEGV错误 代码编译后,调试器会显示指针中的随机地址 use std::ptr; pub struct List<T> { head: *mut Node<T>, tail: *mut Node<T>, } struct Node<T> { data: Option<T>, next: *mut Node<T>, prev: *mut Node<

运行此代码时,我收到一个
SIGSEGV
错误

代码编译后,调试器会显示指针中的随机地址

use std::ptr;

pub struct List<T> {
    head: *mut Node<T>,
    tail: *mut Node<T>,
}

struct Node<T> {
    data: Option<T>,
    next: *mut Node<T>,
    prev: *mut Node<T>,
}

impl<T> List<T> {
    pub fn new() -> Self {
        Self {
            head: ptr::null_mut(),
            tail: ptr::null_mut(),
        }
    }
    pub fn add_tail(&mut self, data: T) {
        let mut new_node = Box::new(Node {
            data: Some(data),
            next: ptr::null_mut(),
            prev: ptr::null_mut(),
        });
        let new_node_ptr: *mut Node<T> = &mut *new_node;
        if self.tail.is_null() {
            self.head = new_node_ptr;
        } else {
            new_node.next = self.tail;
            unsafe {
                (*self.tail).prev = new_node_ptr;
            }
        }
        self.tail = new_node_ptr;
    }
    pub fn remove_tail(&mut self) -> Option<T> {
        if self.tail.is_null() {
            None
        } else {
            let old_tail_ptr = self.tail;
            unsafe {
                if (*old_tail_ptr).next.is_null() {
                    self.tail = ptr::null_mut();
                    self.head = ptr::null_mut();
                } else {
                    let new_tail_ptr = (*old_tail_ptr).next;
                    (*old_tail_ptr).next = ptr::null_mut();
                    (*new_tail_ptr).prev = ptr::null_mut();
                    self.tail = new_tail_ptr;
                }
                (*old_tail_ptr).data.take()
            }
        }
    }
}
使用std::ptr;
发布结构列表{
头部:*mut节点,
尾部:*mut节点,
}
结构节点{
数据:选项,
下一步:*mut节点,
上一页:*mut节点,
}
impl列表{
pub fn new()->Self{
自我{
head:ptr::null_mut(),
tail:ptr::null_mut(),
}
}
发布fn添加_tail(&mut self,数据:T){
让mut new_node=Box::new(node{
数据:部分(数据),
下一步:ptr::null_mut(),
prev:ptr::null_mut(),
});
让新的\u节点\u ptr:*mut节点=&mut*新的\u节点;
如果self.tail.is_null(){
self.head=new_node_ptr;
}否则{
new_node.next=self.tail;
不安全{
(*self.tail).prev=new\u node\u ptr;
}
}
self.tail=new_node_ptr;
}
pub fn remove_tail(&mut self)->选项{
如果self.tail.is_null(){
没有一个
}否则{
让old_tail_ptr=self.tail;
不安全{
if(*old_tail_ptr).next.is_null(){
self.tail=ptr::null_mut();
self.head=ptr::null_mut();
}否则{
让new_tail_ptr=(*old_tail_ptr);
(*old_tail_ptr).next=ptr::null_mut();
(*new_tail_ptr).prev=ptr::null_mut();
self.tail=new\u tail\ptr;
}
(*old_tail_ptr).data.take()
}
}
}
}
我的测试添加了十个整数
0..9
,并弹出它们。在第二次流行音乐中,我得到了

信号:11,SIGSEGV:无效内存引用


以下内容将修复该错误。在
添加_tail

  • 替换
    let new_node_ptr:*mut node=&mut*new_node将新的\u节点\u ptr=Box::放入\u原始(新的\u节点)
  • new\u node.next=self.tail
    替换为
    (*new\u node\u ptr)。next=self.tail
  • 包括
    (*新建节点\u ptr)。下一步=self.tail不安全
    块中的code>
错误是由于从框中错误获取基础指针造成的

let new_node_ptr:*mut node=&mut*new_node
该框继续管理
new\u node\u ptr
指向的内存。在块的末尾,框自动释放内存,使
new\u node\u ptr
悬空


要使用手动内存管理获取指针并从框中释放内存控制,请使用
Box::into_raw
而不是
&mut*

让mut new_node=Box::new
在分配的
节点超出范围后删除
,在
let new_node_ptr:*mut node=&mut*new_node。我真的不知道为什么在这里使用不安全的代码,简单的双链表-我看你还没有被正确地介绍过,如果你关心内存安全的话,这些数据类型到底有多复杂。。。()“我的测试添加了10个整数
0..9
”,这只是9个整数。“正确的解决方法”是根本不使用指针。使用
选项的组合
,您不需要任何原始指针。如果您确实需要它们,请使用
选项
确定不能有空指针。