Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory 为什么Rust会重用具有相同价值的内存_Memory_Rust_Borrow - Fatal编程技术网

Memory 为什么Rust会重用具有相同价值的内存

Memory 为什么Rust会重用具有相同价值的内存,memory,rust,borrow,Memory,Rust,Borrow,示例代码: fn main() { let mut y = &5; // 1 println!("{:p}", y); { let x = &2; // 2 println!("{:p}", x); y = x; } y = &3; // 3 println!("{:p}", y); } 如果第三个赋值包含&3,则代码输出: 0x558e7da926a0 0x558e7

示例代码:

fn main() {
    let mut y = &5; // 1

    println!("{:p}", y);

    {
        let x = &2; // 2
        println!("{:p}", x);
        y = x;
    }

    y = &3; // 3
    println!("{:p}", y);
}
如果第三个赋值包含
&3
,则代码输出:

0x558e7da926a0
0x558e7da926a4
0x558e7da926a8
0x558e7da926a0
0x558e7da926a4
0x558e7da926a4
0x558e7da926a0
0x558e7da926a4
0x558e7da926a0
如果第三个赋值包含
&2
(与第二个赋值值相同),则代码输出:

0x558e7da926a0
0x558e7da926a4
0x558e7da926a8
0x558e7da926a0
0x558e7da926a4
0x558e7da926a4
0x558e7da926a0
0x558e7da926a4
0x558e7da926a0
如果第三个赋值包含
&5
(与第一个赋值值相同),则代码输出:

0x558e7da926a0
0x558e7da926a4
0x558e7da926a8
0x558e7da926a0
0x558e7da926a4
0x558e7da926a4
0x558e7da926a0
0x558e7da926a4
0x558e7da926a0

如果赋值相同,为什么不释放内存,而是重用它?否则,为什么不分配新的内存块?

优化编译器可以使用许多技巧来确定是否可以为变量分配常量值。您的发现与此一致,如果不需要,则无需运行重复的代码。

相同文字编号的两次出现是无法区分的。您不能期望两个文本的地址相同,也不能期望它们不同


这允许编译器(但实际上它可以自由地执行其他操作)在可执行代码中发出一个
5
数据,并让所有
&5
引用它。常量可能(见注释)也有一个静态生存期,在这种情况下,它们在程序执行期间没有分配/取消分配,它们总是被分配的。

当相同的内存可以安全地重复使用时,为什么您希望它分配更多的内存?@Thilo,我想是的,但Rust为什么这样做?我认为Rust可以在第二次和第三次赋值后释放内存。如果没有更重要的东西存储在堆栈中,那么在堆栈上释放一个变量,然后在几条指令后用相同的值重新分配它是没有好处的。如果这些东西是从堆栈中分配的,那么逐个分配和释放它们是非常浪费的。通常,当函数进入/返回时,整个stackframe一次添加/删除。如果它们被“分配”为静态常量,它们根本不需要动态内存管理。@Simson,谢谢我的理解。常量可能被提升为静态,但通常它们也可能成为临时变量或被完全编译掉。5在这里获取静态提升处理,因为代码显式获取其地址;如果不是这样,编译器将可以在寄存器中自由创建或优化它,而二进制文件中根本不会出现5。@trentcl我认为它是有保证的,请参阅@FrenchBoiethios它是有保证的,因为地址是有保证的,但常量通常不受静态提升的影响。我之前的评论是为了澄清答案的一个早期措辞,这可能被解释为意味着所有常数都被提升为静力学,这是不正确的。@trentcl:事实上,如果我知道它不能保证,我不会感到惊讶。具体来说,如果编译器能够省略地址,例如在
let x=&5;普林顿!(“{}”,1+*x)
那么我不希望在二进制文件的数据部分中找到文本
5
,我希望看到直接嵌入到程序集中的
6