How to initialize the uinit array element by element?

    1 pub struct rc4_stat {
    2     m: u8,
    3     n: u8,
    4     key: [u8; 256],
    5 }
    6 
    7 impl rc4_stat {
    8     pub fn new(key: &str) -> rc4_stat {
    9         use std::mem::MaybeUninit;
   10         use std::ptr;
   11 
   12         let mut uninit = MaybeUninit::<rc4_stat>::uninit();
   13         unsafe {
   14             let p = ptr::addr_of_mut!((*uninit.as_mut_ptr()).m);
   15             p.write(0);
   16             let p = ptr::addr_of_mut!((*uninit.as_mut_ptr()).n);
   17             p.write(0);
   18 
   19             let p: *mut [u8; 256] = ptr::addr_of_mut!((*uninit.as_mut_ptr()).key);
   20             for i in 0..256 {
   21                 ......................... 
   22             }
   23             uninit.assume_init()
   24         }
   25     }
   26 }
   27 

For code above, How to write the line 21 to init the array?

p.cast::<u8>().offset(i).write(0) is probably the most direct way.

Note that you can write also write array directly, not using loop (at that point, however, it becomes unclear why do you need a MaybeUninit at the first place).

1 Like

It doesn't seem like you need MaybeUninit or any unsafe here at all. The whole function can be simplified to 3 lines:

pub fn new(key: &str) -> rc4_stat {
    let mut bytes = [0; 256];
    bytes.copy_from_slice(key.as_bytes());
    rc4_stat { m: 0, n: 0, key: bytes }
}

(assuming copying the key verbatim is what you wanted – it's not clear from your post.)

Good point -- if it's being returned by value anyway, doing a MaybeUninit dance like this probably doesn't help at all.

1 Like

It will not be initialized to zero,

        let (mut stat, key) = unsafe {
            let mut key = MaybeUninit::<[Wrapping<u8>; 256]>::uninit();
            let mut stat = MaybeUninit::<rc4_stat>::uninit();
            let kbin = k.as_bytes();

            let p = ptr::addr_of_mut!((*stat.as_mut_ptr()).m);
            p.write(Wrapping(0));
            let p = ptr::addr_of_mut!((*stat.as_mut_ptr()).n);
            p.write(Wrapping(0));

            let p1 = ptr::addr_of_mut!((*stat.as_mut_ptr()).key);
            let p2 = key.as_mut_ptr();
            for i in 0..=255 {
                p1.cast::<Wrapping<u8>>().offset(i).write(Wrapping(i as u8));
                p2.cast::<Wrapping<u8>>()
                    .offset(i)
                    .write(Wrapping(kbin[(i as usize) % k.len()]));
            }
            (stat.assume_init(), key.assume_init())
        };