-1

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

以下段落摘自 Book Rust for Rustaceans:

在跳转到定义的开始符号之前真正不运行代码的平台上,像大多数嵌入式设备一样,静态变量的初始值甚至可能与源代码中指定的值不匹配。在这种情况下,您的初始化函数将需要使用程序二进制文件中指定的初始数据值显式初始化各种静态内存段。

我有与上面段落完全相同的问题。在运行时,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 {}
}
4

1 回答 1

1

我换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 ᶠᵒʳᵐᵉʳˡʸ ᶜˡ</p>

于 2022-01-07T13:51:36.297 回答