c++ - 为什么填充也放在聚合类型的末尾,而不仅仅是成员之间?
问题描述
我大致了解 Alignment 并阅读了cppreference 的 Objects and alignment 和Wikipedia 的 Data structure alignment 。不过我还是有些疑惑。我主要对 C++ 感兴趣,但这个问题也适用于 C,因为它使用几乎相同的对齐规则。
我知道添加填充是为了提高数据访问的效率,因为在某些体系结构上,访问地址倍数的值会更快/更好(对齐)。
- 这是使用填充的唯一原因吗?
如果是这样,请考虑以下结构:
struct A {
int i;
char c;
};
struct B {
struct A a;
char d;
};
在我的体系结构 (x86_64) 上,编译器将 3 个字节的填充放在A
so thatsizeof(A)==8
和的末尾,并将其他 3 个字节的填充放在, sosizeof(A[2])==16
的末尾。B
sizeof(B)==12
我知道对齐A
到 8 个字节可以更有效地将其存储在数组中。但它似乎一点用都没有,什么时候A
放在里面B
。
如果到目前为止一切都是正确的,那么我想知道:
- 为什么将填充放在类型的末尾,而不是将其限制在聚合类型(例如结构或数组)的元素之间,而不是放在末尾?
我的意思的一个例子:如果编译器决定sizeof(A)==5
, sizeof(B)==6
, sizeof(A[2])==13
(元素之间的 3 个字节的填充,但不是在最后),那不是更好吗?
解决方案
int
考虑一个需要 4 字节对齐(或性能需要)的架构。现在考虑以下结构:
struct S {
int i;
char c;
}
和之间可能不会有任何填充。但是现在想想如果你定义类似的东西会发生什么:i
c
struct S array[10];
由于数组不允许在元素之间有任何填充,因此必须将此填充添加到S
结构中 - 在结构的末尾(在 之后 3 个字节c
),以保持.array
推荐阅读
- angular - 基于每个点的值的具有渐变的颜色点
- php - PHP - preg_replace_callback 因子标签而失败
- php - 如何使用 php xmlreader 读取 xml 文件
- asp.net-mvc - 为什么 AnonymousObjectToHtmlAttributes 返回一个路由值字典
- c# - 从 API 方法返回 JSON
- vbscript - 文件上传后如何将文件名变量从子asp页面传递到父页面
- python - 具有时间序列日期的线性回归训练
- c# - 当属性对象被无根并标记为垃圾收集时?
- python - 为什么我收到错误“无法加载外部图块集”
- html - flexbox中的中心div