静态变量的初始值甚至可能与源代码中指定的值不匹配

The initial values of static variables may not even match what’s specified in the source code

我正在从事一个围绕嵌入式系统的项目。所以我必须实现一个 alloc 方法来分配一个新的内存段,并实现 dealloc 来将过去的分配返回给分配器以供重用。

以下段落摘自 Book Rust for Rustaceans:

On platforms that truly run no code before they jump to the defined start symbol, like most embedded devices, the initial values of static variables may not even match what’s specified in the source code. In such cases, your initialization function will need to explicitly initialize the various static memory segments with the initial data values specified in your program binary.

我遇到的问题与上一段完全相同。在 运行 时间,Rust 分配了非常大的堆内存。有人能解决这个问题吗?

此代码适用于 Linux 但不适用于我的设备。因为 Rust 对内存的要求远远大于我设备的容量。

pub struct Heap {
    pub vector: Vec<u8>,
}

pub static mut MY_HEAP: Option<Heap> = None;

fn main() {
    unsafe {
        MY_HEAP = Some(Heap {
            vector: vec![1, 2, 3],
        })
    };
    unsafe {
        match &mut MY_HEAP {
            Some(h) => {
                println!("{:?}", h.vector);
            }
            None => (),
        }
    }
}

您可以在下面看到分配器的实现:

#![feature(allocator_api)]
#![feature(alloc_error_handler)]
#![no_std]
#![crate_name = "ql_alloc"]
#![crate_type = "rlib"]

use ql_sys as ql;
use core::alloc::{GlobalAlloc, Layout};
pub struct QLAllocator;

unsafe impl GlobalAlloc for QLAllocator {
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
        let a = ql::Ql_MEM_Alloc(layout.size() as u32) as *mut u8;
        a
    }
    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
        ql::Ql_MEM_Free(ptr as *mut _ as *mut cty::c_void);
    }
}

#[alloc_error_handler]
fn on_oom(layout: Layout) -> ! {
    loop {}
}

我将 MY_HEAP = Some(...) 替换为 core::ptr::write(&mut MY_HEAP, Some(...)),问题已解决。

pub struct Heap {
    pub vector: Vec<u8>,
}

pub static mut MY_HEAP: Option<Heap> = None;

fn main() {
    unsafe {
        assert!(MY_HEAP.is_none());
    }
    unsafe {
        core::ptr::write(
            &mut MY_HEAP,
            Some(Heap {
                vector: vec![1, 2, 3],
            }),
        );
    };
    unsafe {
        match &mut MY_HEAP {
            Some(h) => {
                println!("{:?}", h.vector);
            }
            None => (),
        }
    }
}

感谢 trent ᶠᵒʳᵐᵉʳˡʸ ᶜˡ