>>107514611
Well, I wouldn't create "rather large" 2D array on stack.
You need to make your own structure explicitly anyway, there is no compiler magic that will do it for you.
I would personally write my own structure that holds width, height and vec, and some extra structures for "array views" which can hold strides in order to archive 2D slices like arr[1..10][2..20]. There is probably many crates that do this already but it's also not hard to make one yourself.
However if you want to archive same thing as your C code, it can be done using unsized structure.
#![feature(ptr_metadata)]
#![feature(layout_for_ptr)]
#![feature(thread_local)]
use std::{ptr, alloc};
use std::alloc::Layout;
#[repr(C)]
#[derive(Debug)]
struct Array2D {
width: usize,
data: [i32],
}
impl Array2D {
fn new(width: usize, height: usize) -> Box<Array2D> {
let len = width * height;
let ptr: *const Array2D = ptr::from_raw_parts(ptr::null::<u8>(), len);
unsafe {
let layout = Layout::for_value_raw(ptr).pad_to_align();
let ptr = alloc::alloc(layout);
if ptr.is_null() {
alloc::handle_alloc_error(layout);
}
let (address, _) = ptr.to_raw_parts();
let ptr: *mut Array2D = ptr::from_raw_parts_mut(address, len);
(&raw mut (*ptr).width).write(width);
(&raw mut (*ptr).data as *mut u8).write_bytes(0, len * size_of::<i32>());
Box::from_raw(ptr)
}
}
}
static mut STATIC_ARR: Option<&'static Array2D> = None;
fn main() {
let arr = Array2D::new(10, 20);
println!("{}", size_of_val(&*arr));
// it can be referenced in a struct!
#[derive(Debug)]
struct Wrapper<'a> {
arr: &'a Array2D,
}
let wrapped = Wrapper { arr: &arr };
println!("{:?}", wrapped);
// In a static too!
#[allow(static_mut_refs)]
unsafe {
STATIC_ARR = Some(Box::leak(arr));
println!("{:?}", STATIC_ARR);
}
}