Rust lang的内存管理基础

ubbxdtey  于 2023-02-08  发布在  其他
关注(0)|答案(1)|浏览(172)

我需要一些帮助来理解生 rust 的基础知识和记忆的基础知识。我想这对那些在我之后遇到这个的人会有帮助。

内存地址

(1)这里我创建了一个函数,它返回指向一个向量的指针。如果必须有相同的指针,为什么会有两个不同的地址?

fn get_pointer(vec: &[i32]) -> &[i32] {
    vec
}
fn main() {
    let vector = vec![1, 2, 3, 4, 5];

    let first_element = get_pointer(&vector);
    let vector: Vec<String> = Vec::new();
    println!(
        "Vector: {:p}, and func result: {:p}",
        &vector, first_element
    );
}

输出:矢量:0x5181aff7e8,函数结果:0x17e5错误99b0
一个元素的不同地址?
(2)现在我正在创建一个函数,它返回一个指向Vector的第一个元素的指针

fn get_pointer_to_first_element(vec: &[i32]) -> &i32 {
    &vec[0];
} 

fn main() {
    let vector = vec![1, 2, 3, 4, 5];

    let first_element = get_pointer_to_first_element(&vector);

    println!(
        "from variable: {:p}, from function: {:p}",
        &vector[0], &first_element
    );
}

从变量:0x1f9a887da80,来自函数:0x15铁2ffb10

函数中定义的变量

(3)* 好吧,我知道这个问题更愚蠢,但我真的不明白 *
这里我在一个函数中创建了一个指针变量,当程序离开函数的作用域时,它必须和它的“值”一起删除,那么为什么我可以在调用函数后使用那个值呢?
还有一个关于隐藏后删除值的问题,是真的吗?为什么?

fn get_pointer_to_first_element(vec: &[i32]) -> &i32 {
    let pointer = &vec[0];
    pointer
} // here variable "pointer" and its value must be deleted, isn't it? how then i can operate it after calling a function?

fn main() {
    let vector = vec![1, 2, 3, 4, 5];

    let first_element = get_pointer_to_first_element(&vector);

    let vector: Vec<String> = Vec::new(); // Bonus question: "vector" variable is new now, so previous must be deleted?

    println!("first element is available and its {first_element}. ");
}

向量:0x5181aff7e8,函数结果:0x17e5错误99b0
我试着对数组使用同样的方法,但结果是一样的。

fnvucqvd

fnvucqvd1#

按顺序:
1.你分配了一个新的向量,所以它当然会有一个不同的地址。first_element指向原始向量。它是用那个值初始化的,并且会保留它。**即使你没有,**你的函数也会把slice作为参数;而不是Vec。它们是不同的类型。Vec本身是一个指针。slice是一个单独的引用,顾名思义,它指向堆上的一个数据切片。

fn main() {
    let vector = vec![1, 2, 3];

    println!(
        "Normal: {:p}. Calculated /w a function: {:p}. Slice: {:p}.",
        &vector,
        get_vec_address(&vector),
        get_slice_address(&vector)
    );

    // This outputs:
    // Normal: 0x7fff91db1550. Calculated /w a function: 0x7fff91db1550. Slice: 0x55ddbc54a9d0.
}

fn get_vec_address(vec: &Vec<i32>) -> &Vec<i32> {
    vec
}

/// `&vector` is coerced from `&Vec` into `&[i32]`.
/// To learn more about Deref coercions, go to:
/// https://doc.rust-lang.org/book/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods
fn get_slice_address(slice: &[i32]) -> &[i32] {
    slice
}

Run this snippet on Rust Playground.有关直观的说明,请参阅此容器备忘单。
1.正如评论所说,你是在引用一个引用的引用。

  1. pointer没有被删除。它作为返回值被移动。为了更好地理解作用域,您可能需要查看有关作用域和lifetimes的章节。
    至于你的额外问题,隐藏变量并不会删除它。它仍然会生存到作用域的末尾。如果存在对它的引用,它仍然可以使用。例如,下面是有效的代码:
fn main() {
    let vector = vec![1, 2, 3];
    let first_element = &vector[0];
    let vector = vec![4, 5, 6];
    
    println!("{first_element}");
    println!("{vector:?}");

    // This will print:
    // 1
    // [4, 5, 6]
}

Run this snippet on Rust Playground.

相关问题