-
Notifications
You must be signed in to change notification settings - Fork 173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[第四章] 关于结构体对齐规则 #56
Comments
116页,图4-11应该也是同样问题 关于struct重排这个,搜了下rust文档有一些描述 |
@wucheng 感谢反馈。我看看先。 |
读 102 页的时候特别困惑。感谢你对这个问题的分析,并给出相关文档。 |
已经有读者反映就不需要重开 issue 了~ 看这节时没理解找文档看了下,作者对于内存布局解释确实有错误,先不说 rust 的内存布局。 书中 102 页倒数第2行“那么对于成员 a 来说,它的对齐值为 MIN(4, 1), 即 1, 所以 a 需要补齐一个字节的空间” 成员 a 的 大小和对齐值都是1,所以它可以存在任何地址,是不需要补齐的。到下一个字段 b ,它需要偏移地址是 4 的倍数 ,所以需要填充 3 个字节。到字段 c , 因为加上 b 的大小的偏移,这时候的偏移已经是 4 的倍数了,所以 c 也不需要补齐。但是 struct 的对齐值等于其字段对齐值的最大值,也就是 4 ,所以要在 c 后面 补齐 2 个字节,使 struct 大小是 4 的倍数。这种布局有 5 个字节大小的内存浪费,如果我们调整字段顺序,只需要在最后补齐1个字节 #[repr(C)]
struct A {
b: u32,
c: u16,
a: u8,
}
fn main() {
println!("{:?}", std::mem::size_of::<A>()); // 8
let v = A { a: 1, b: 2, c: 3 };
println!("&v {:p}", &v);
println!("&v.b {:p}", &v.b);
println!("&v.c {:p}", &v.c);
println!("&v.a {:p}", &v.a);
} 以上说的是 repr(c) 的布局方式,rust 默认布局 struct 字段顺序是不确定的,编译器会进行优化调整字段顺序,以避免内存浪费的情况 参考
|
@yim7 感谢反馈。这部分还没抽出时间来确认,这周内看看。后续贴出更正内容。 |
你这个例子应该修改为: #![allow(unused)]
#[repr(C)]
struct A {
a: u8,
b: u32,
c: u16,
}
fn main() {
println!("{:?}", std::mem::size_of::<A>()); // 12
let v = A { a: 1, b: 2, c: 3 };
} 才能看出没有重排的效果。是浪费了5个字节。 |
页码与行数
struct结构体对齐的规则,结构体A的长度是8个字节,但是内存布局不应该是图中所示a后面补充了1个字节,因为如果是这样,b的开始地址也不是4字节对齐的。
最终struct A是8个字节,是因为编译器对结构体成员进行了地址重排,先后顺序是b, c, a
如输出的其实地址所示
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=83128ce39b5e1b3ca58e77035f1111c5
文本或排版错误
The text was updated successfully, but these errors were encountered: