0

我正在尝试在不安全的 Rust 中实现二叉树,它似乎是调试和发布之间的区别。

在调试时执行的这段代码很可能访问错误的内存地址,但如果在发布模式下编译它似乎没问题。

我完全有可能犯了一个错误,因为我对原始指针很陌生,但是有不同的输出真的很奇怪。

我的不同输出真的是错误内存访问的标志吗?使用不安全的 Rust 时,这是预期的吗?这是代码气味的标志吗?

在调试模式下,我机器上的输出是:

constructing tree
5
constructed
0.000000000000000000000000000000000000000000001
value added

在发布模式下,我机器上的输出是:

constructing tree
5
constructed
5
value added

这里的代码,尽可能地减少。

use std::ptr;

struct Node {
    value: f32,
    node_left: *mut Node,
    node_right: *mut Node,
}

impl Node {
    pub fn from_value(value: f32) -> Node {
        println!("{}", value);
        Node {
            value: value,
            node_left: ptr::null_mut(),
            node_right: ptr::null_mut(),
        }
    }

    fn get_value(&self) -> f32 {
        self.value
    }
}

pub struct BinaryTree {
    root: *mut Node,
}

impl BinaryTree {
    pub fn from_value(value: f32) -> BinaryTree {
        let mut node = &mut Node::from_value(value);
        BinaryTree { root: node }
    }

    pub fn add(&mut self, value: f32) {
        println!("{}", unsafe { self.root.as_mut() }.unwrap().get_value());
    }
}

fn main() {
    println!("constructing tree");
    let mut x = BinaryTree::from_value(5.0f32);
    println!("constructed");
    x.add(2f32);
    println!("value added");
}

我在 Ubuntu 18.04 上使用 Rust 1.32.0 在 Oracle VM 上运行了它。

4

1 回答 1

2

BinaryTree::from_value中,您正在创建一个新的Node,然后存储一个指向它的指针。但是,Node是在堆栈上分配的,并在您调用之前被删除BinaryTree::add。因为您使用的是指针而unsafe不是引用,所以 Rust 编译器无法警告您此类生命周期问题。

至于为什么这在调试模式下失败但在发布模式下工作,可能是由于仅对发布模式启用的优化。

于 2019-02-22T19:22:08.417 回答