How to write & read a vec of struct with unaligned fields?
⚓ Rust 📅 2025-09-21 👤 surdeus 👁️ 7This is a continuation of this thread. I have a struct like this:
struct MyStruct {
other_items_offset: u32,
foo: u32,
bar: u8,
baz: u8
}
It's not 32- or 64-bit aligned, I know. I just created it this way to see it with the smallest possible fields.
And I have a vector of them (about 100K items), that I want to save into a file, and then in another Rust binary in the same project, I want to read them into a vector (not mem-map, because I want to resize the vector, and for now it's just too complicated for me).
I tried to write it with Zerocopy. If a struct has just several u64's, everything is fine. But with this one, the approach won't work.
The derive macros don't work:
use zerocopy::{FromBytes, IntoBytes, Immutable};
#[derive(Debug, FromBytes, IntoBytes, Immutable)]
^^^^^^^^^
`graph::VertexData` has inter-field padding
consider using `zerocopy::Unalign` to lower the alignment of individual fields
consider adding explicit fields where padding would be
consider using `#[repr(packed)]` to remove inter-field padding
the trait `PaddingFree<graph::VertexData, true>` is not implemented for `()`
but trait `PaddingFree<graph::VertexData, false>` is implemented for it
see issue #48214
I add #[repr(packed)] and then my test cases fail:
data_vec.iter().enumerate().for_each(|(i, v)| println!("rec {}, {}", i, v.other_items_offset));
^^^^^^^^^^^^^^^^^^^^
reference to packed field is unaligned
packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
What can I do to pack it and unpack into binary files?
I could, of course, write my own pack/unpack routine, but I hope there's a better way.
4 posts - 3 participants
🏷️ Rust_feed