gpt4 book ai didi

pointers - 接受字符串引用的函数参数是否直接指向字符串变量或 Rust 堆上的数据

转载 作者:行者123 更新时间:2023-12-03 11:35:24 25 4
gpt4 key购买 nike

我从 The Rust Book 拍摄了这张照片和代码.
为什么s指向s1而不仅仅是堆本身的数据?
如果是这样,它是如何工作的? s 如何指向s1 .是否使用包含 s1 内存地址的 ptr 字段分配内存? .那么,s1 , 又指向数据。
s1 ,我似乎正在查看一个带有指针、长度和容量的变量。只是ptr在此处输入实际指针?
这是我的第一个系统级语言,所以我认为与 C/C++ 的比较不会帮助我理解这一点。我认为部分问题在于我不太了解指针到底是什么以及操作系统如何分配/取消分配内存。
Pointer

fn main() {
let s1 = String::from("hello");

let len = calculate_length(&s1);

println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize {
s.len()
}

最佳答案

  • 内存 只是一个巨大的数组,可以通过任何偏移量进行索引(例如 u64 )。
  • 这个偏移量称为 地址 ,
  • 和一个存储地址的变量,称为 指针 .
  • 然而,通常只有一小部分内存是 已分配 ,所以不是每个地址都是有意义的(或有效的)。
  • 分配是对程序有意义的(顺序)地址范围的请求(因此它可以访问/修改)。
  • 每个对象(我指的是任何类型的对象)都位于分配的内存中(因为未分配的内存对程序毫无意义)。
  • 引用 实际上是一个指针,它(由编译器)保证是有效的(即从编译器已知的某个对象的地址派生)。看看std doc还。

  • 以下是这些概念的一个示例( playground):
    // This is, in real program, implicitly defined,
    // but for the sake of example made explicit.
    // If you want to play around with the example,
    // don't forget to replace `usize::max_value()`
    // with a smaller value.
    let memory = [uninitialized::<u8>(); usize::max_value()];

    // Every value of `usize` type is valid address.
    const SOME_ADDR: usize = 1234usize;

    // Any address can be safely binded to a pointer,
    // which *may* point to both valid and invalid memory.
    let ptr: *const u8 = transmute(SOME_ADDR);

    // You find an offset in our memory knowing an address
    let other_ptr: *const u8 = memory.as_ptr().add(SOME_ADDR);

    // Oversimplified allocation, in real-life OS gives a block of memory.
    unsafe { *other_ptr = 15; }

    // Now it's *meaningful* (i.e. there's no undefined behavior) to make a reference.
    let refr: &u8 = unsafe { &*other_ptr };
    我希望澄清大多数事情,但让我们明确地涵盖这些问题。

    Why does s point to s1 rather than just the data on the heap itself?

    s是一个引用(即有效指针),所以它指向 s1的地址.它可能(并且可能会)被编译器优化为与 s1 相同的内存。 ,从逻辑上讲,它仍然是指向 s1 的不同对象。 .

    How does the s point to s1. Is it allocated memory with a ptr field that contains the memory address of s1.


    “指向”的链条仍然存在,所以调用 s.len()内部转换为 s.deref().len , 并访问转换为 s.deref().ptr.add(index).deref() 的字符串数组的某个字节.
    图片上显示了3 block 内存: &s , &s1 , s1.ptr是不同的(除非优化)内存地址。所有这些都存储在分配的内存中。前两个实际上存储在称为 的预分配(即在调用 main 函数之前)内存中。堆栈 通常是 它不称为分配的内存 (虽然我在这个答案中忽略了这种做法)。 s1.ptr相反,指针指向由用户程序显式分配的内存(即在输入 main 之后)。

    In s1, I appear to be looking at a variable with a pointer, length, and capacity. Is only the ptr field the actual pointer here?


    对,就是这样。长度和容量只是常见的无符号整数。

    关于pointers - 接受字符串引用的函数参数是否直接指向字符串变量或 Rust 堆上的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62820790/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com