如何创建一个带有嵌入式切片的无大小类型的智能指针?

问题描述

我正在尝试通过使用类似C的flexible-array成员的方法来避免多个堆分配。为此,我需要分配一个未调整大小的结构,但是我找不到通过智能指针执行此操作的任何方法。我对Rc特别感兴趣,但是Box也是如此,因此我将在示例中使用。

这是我到目前为止最接近的一个

use std::alloc::{self,Layout};

struct Inner {/* Sized fields */}

#[repr(C)] // Ensure the array is always last
// Both `inner` and `arr` need to be allocated,but preferably not separately
struct Unsized {
    inner: Inner,arr: [usize],}

pub struct Exposed(Box<Unsized>);

impl Exposed {
    pub fn new(capacity: usize) -> Self {
        // Create a layout of an `Inner` followed by the array
        let (layout,arr_base) = Layout::array::<usize>(capacity)
            .and_then(|arr_layout| Layout::new::<Inner>().extend(arr_layout))
            .unwrap();
        let ptr = unsafe { alloc::alloc(layout) };
        // At this point,`ptr` is `*mut u8` and the compiler doesn't know the size of the allocation
        if ptr.is_null() {
            panic!("Internal allocation error");
        }
        unsafe {
            ptr.cast::<Inner>()
                .write(Inner {/* Initialize sized fields */});
            let tmp_ptr = ptr.add(arr_base).cast::<usize>();
            // Initialize the array elements,in this case to 0
            (0..capacity).for_each(|i| tmp_ptr.add(i).write(0));
            // At this point everything is initialized and can safely be converted to `Box`
            Self(Box::from_raw(ptr as *mut _))
        }
    }
}

无法编译:

error[E0607]: cannot cast thin pointer `*mut u8` to fat pointer `*mut Unsized`
  --> src/lib.rs:32:28
   |
32 |         Self(Box::from_raw(ptr as *mut _))
   |                            ^^^^^^^^^^^^^

我可以直接与*mut u8合作,但这似乎极易出错,需要手动删除。

因为实际上我知道分配大小,还是有办法从ptr创建胖指针,还是从复合无大小类型创建智能指针?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)