为何这段Rust代码会在同一内存区域分配缓冲区?
你的RTOS代码中栈指针重复的原因及修复方案
你运行代码后会发现三个PCB的栈指针(sp)输出相同的地址,这是因为你保存的是悬垂指针,而非结构体中实际栈内存的有效地址。
问题根源
- 在
Stack::new()中,你首先创建了局部变量mem,并获取它的指针赋值给sp。 - 随后你将这个局部
mem移动到Stack结构体中,此时mem的实际存储位置已经改变——从Stack::new()的函数栈帧,转移到main栈帧中对应PCB结构体的位置。 - 但你保存的
sp仍然指向原来局部变量mem的地址,这个地址在Stack::new()返回后已经被释放,属于悬垂指针。 - 调试模式下,编译器重复利用了
Stack::new()栈帧中mem的位置,所以三个sp显示相同的无效地址。
修复方案
你需要在mem被移动到结构体后,再获取它的指针,这样才能得到结构体内部栈内存的有效地址。修改Stack::new()如下:
impl<const WORDS: usize> Stack<WORDS> { pub fn new() -> Self { let mut stack = Self { sp: StackPointer(core::ptr::null()), mem: [0; WORDS], }; // 获取结构体内部mem的有效指针 stack.sp = StackPointer(stack.mem.as_ptr()); stack } }
修改后运行,三个sp会显示不同的有效地址,符合RTOS中每个任务栈独立的预期。
额外提醒
在Rust中,局部变量的生命周期仅限于当前函数栈帧,移动操作会转移数据所有权但不会保留原地址。直接保存局部变量的指针必然导致悬垂指针,这在RTOS这类对内存安全性要求极高的场景中必须严格避免。
内容的提问来源于stack exchange,提问作者Fabio Zanin
相关产品推荐
相关产品推荐

