Rust 如何判断是分配了堆还是堆栈?

Rust 如何判断是分配了堆还是堆栈?,rust,heap-memory,stack-memory,Rust,Heap Memory,Stack Memory,我想知道是否有办法确定变量是堆栈还是堆分配的 考虑这一点: struct SomeStruct; fn main() { let some_thing = Box::new(SomeStruct); println!("{:p}", some_thing); foo(&*some_thing); } fn foo (bar: &SomeStruct) { println!("{:p}", bar); } 印刷品 0x1 0x1 0x1069

我想知道是否有办法确定变量是堆栈还是堆分配的

考虑这一点:

struct SomeStruct;

fn main() {
    let some_thing = Box::new(SomeStruct);
    println!("{:p}", some_thing);
    foo(&*some_thing);
}

fn foo (bar: &SomeStruct) {
    println!("{:p}", bar);
}
印刷品

0x1
0x1
0x10694dcc0
0x10694dcc0
然后

struct SomeStruct;

fn main() {
    let some_thing = &SomeStruct;
    println!("{:p}", some_thing);
    foo(some_thing);
}

fn foo (bar: &SomeStruct) {
    println!("{:p}", bar);
}
印刷品

0x1
0x1
0x10694dcc0
0x10694dcc0

我可以看出,对于堆分配的版本,内存地址要短得多,但我不知道这是否是区分差异的可靠方法。我想知道是否有类似于
std::foo::is_heap_allocated()

的东西如果您在某个POSIX系统上,您可能可以使用参数为
0
的系统调用来确定程序中断的当前位置,这是堆的当前限制。如果给定值的地址小于此地址但大于堆的起始地址,则它位于堆上。我不知道如何检查它是否在堆栈上,这不一定是不在堆上的自动选择,因为它也可以是静态初始化或未初始化的数据,尽管在检查代码时,这可能对您来说很明显。您可能可以在x86_64体系结构上使用
rbp
寄存器,该寄存器应指向当前堆栈帧的开头。如果要检查它是否在当前堆栈帧上,或者如果要检查它是否在堆栈上的任何位置,则可以使用
rsp


我认为您可以使用
end
参数通过系统调用获得堆的开始。因此堆的下限是
end(end)
的结果,上限是
sbrk(0)

首先想到的问题是“为什么?”。有了这些知识,什么样的代码会有不同的工作方式?我不需要这些代码,只需要更多地发现语言:
0x1
是Rust分配器为零大小对象返回的虚拟地址,它不在堆上。看,我也有同样的问题。我想知道,因为我感兴趣的是这东西在引擎盖下是如何工作的。例如,这个简单的示例似乎显示了几乎连续地址中的所有内容。我现在想知道是否所有对堆的引用都会占用堆栈空间,它会给我对堆的堆栈引用的地址。大多数现代POSIX系统(/分配器)使用
mmap
来获取堆空间,而不是
(s)brk
(s)brk
在macOS上被正式弃用(将触发警告),在大多数BSD上也被非正式弃用(它们被称为“历史珍品”)。我认为正确的方法是获取堆栈基(
pthread\u attr\u getstackaddr
),即当前堆栈指针,并检查指针是否位于两者之间。