Memory management 如何在函数中初始化堆上的静态结构?

Memory management 如何在函数中初始化堆上的静态结构?,memory-management,rust,heap-memory,Memory Management,Rust,Heap Memory,我有一个全局结构,它存储我的对象并具有复杂的行为。 除了数据,它还有一个对象的全局id生成器。他们的工作也需要他们 use std::sync::{Arc, Mutex}; static mut system_ptr: *mut Box<System> = 0 as *mut Box<System>; struct System { data: Vec<Data>, id_mutex: Arc<Mutex<u32>>

我有一个全局结构,它存储我的对象并具有复杂的行为。 除了数据,它还有一个对象的全局id生成器。他们的工作也需要他们

use std::sync::{Arc, Mutex};

static mut system_ptr: *mut Box<System> = 0 as *mut Box<System>;

struct System {
    data: Vec<Data>,
    id_mutex: Arc<Mutex<u32>>,
}

impl System {
    fn get_new_id() -> u32 {
        unsafe {
            let s = &mut *system_ptr;
            let mut data = s.id_mutex.lock().unwrap();
            *data += 1;
            *data
        }
    }
}
使用std::sync::{Arc,Mutex};
静态mut系统\u ptr:*mut Box=0作为*mut Box;
结构系统{
资料来源:Vec,
id_互斥体:弧,
}
impl系统{
fn获取新id()->u32{
不安全{
设s=&mut*system\u ptr;
让mut data=s.id_mutex.lock().unwrap();
*数据+=1;
*资料
}
}
}
我正在初始化该结构,如下所示:

fn main() {
    let s = System{data: Vec::new(), id_mutex: Arc::new(Mutex::new(0 as u32))};
    let mut s_box = Box::new(s);
    unsafe {
        system_ptr = &mut s_box as *mut Box<System>;
    }

    // here I have some work with the initialized "System"

}
fn main(){
设s=System{data:Vec::new(),id_mutex:Arc::new(mutex::new(0作为u32))};
让mut s_box=box::new(s);
不安全{
system_ptr=&mut s_box as*mut box;
}
//在这里,我对初始化的“系统”做了一些工作
}
当我将初始化代码从
main()
移动到某个函数时,
被删除,出现“释放后使用”错误和崩溃

我曾尝试使用
&'static
,但目前对Rust的语义还不够流利,或者这是个坏主意

无论如何,如何将某些
的初始化内存(原始指针)移动到函数或方法

编辑:这不是关于单例的问题,而是关于任何堆变量的初始化。马特,谢谢你的理解

您可能需要使用板条箱来初始化静态变量,这样就不需要处理原始指针

但如果你真的想自己处理,你可以这样做:

static mut system_ptr: *mut System = 0 as *mut System;

fn init() {
    let mut system = Box::new(System(Vec::new()));
    unsafe {
        system_ptr = &mut *system;
    }
    std::mem::forget(system);
}
将该框传递到std::mem::forget
会故意泄漏它,确保其析构函数永远不会运行。我们不存储指向长方体的指针(它本身只是本地堆栈变量中的指针),而是直接存储指向堆上的值的指针

即将发布的Rust 1.4版本将有一个
Box::into_raw
函数,可以为您处理所有这些。如果升级到Rust 1.4(目前在beta频道上),则可以将上述代码替换为:

fn init() {
    unsafe {
        system_ptr = Box::into_raw(Box::new(System(Vec::new())));
    }
}

这真的只是重复的吗?为什么你觉得这个问题不是重复的?这里有两个问题。一个是“如何初始化静态变量”,这肯定是重复的。但另一个问题是“如何从一个框中正确初始化一个原始指针”,这是我关注的部分。