one*_*ero 0 c stack-memory rust borrow-checker stack-pointer
我有一个小的 C 代码,它通过修改堆栈地址处的数据来演示运行时堆栈功能。
#include <stdio.h>
int * fun() {
int a = 10;
return &a;
}
int * fun2() {
int b = 20;
return &b;
}
int main () {
int *a = fun();
int *b = fun2();
printf("a:%d b:%d\n", *a, *b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
其输出为:a:20 b:20,显示“fun2”中的“b”使用与“fun”中的“a”相同的堆栈地址。
我也想在 Rust 中测试这个。做到这一点最简单的方法是什么?
我尝试借用,但编译器说“没有借用价值”。
如果你想拥有与 C 中相同的未定义行为,你可以这样做(幸运的是,这需要unsafe):
fn fun() -> *const i32 {
let a = 10;
&a
}
fn fun2() -> *const i32 {
let b = 20;
&b
}
fn main() {
let a = fun();
let b = fun2();
// SAFETY: Don't do this. This is pure Undefined Behavior.
unsafe {
println!("a: {} b: {}", *a, *b);
}
}
Run Code Online (Sandbox Code Playgroud)
这就是 UB,与 C 版本完全相同。它在调试模式和发布模式下打印a: 21885 b: 21885在 Playground 上。a: -482758656 b: 32767你的会有所不同。
如果您还想要与 C 版本相同的结果,您可以使用printf(). 请小心您使用的代码,更改可能会导致它不再“工作”,因为它将使用不同的堆栈布局。当然,这是非常脆弱的:
use std::ffi::c_char;
fn fun() -> *const i32 {
let a = 10;
&a
}
fn fun2() -> *const i32 {
let a = 20;
&a
}
extern "C" {
fn printf(format: *const c_char, ...);
}
fn main() {
let a = fun();
let b = fun2();
unsafe {
printf(b"a: %d b: %d\n\0" as *const u8 as *const c_char, *a, *b);
}
}
Run Code Online (Sandbox Code Playgroud)
它a: 20 b: 20在调试模式和a: 1 b: 1发布模式下打印(并且您的可能不同)。
| 归档时间: |
|
| 查看次数: |
296 次 |
| 最近记录: |