了解 C 中的内存对齐约束和填充字节
Understanding memory alignment constraints and padding bytes in C
我有以下代码片段。
#include<stdio.h>
int main(){
typedef struct{
int a;
int b;
int c;
char ch1;
int d;
} str;
printf("Size: %d \n",sizeof(str));
return 0;
}
输出如下
Size: 20
我知道 structure
的大小大于 structure
的组件大小的总和,因为添加了填充以满足内存对齐约束。
我想知道如何决定必须添加多少字节的填充。它取决于什么?它取决于 CPU 体系结构吗?它也取决于编译器吗?我在这里使用 64 位 CPU 和 gcc
编译器。如果这些参数发生变化,输出将如何变化。
我知道 Whosebug 上有类似的问题,但他们没有彻底解释这个内存对齐约束。
我知道这取决于CPU架构,我想你可以在网上找到一些有趣的文章来谈论这个,wikipedia我觉得还不错。
对我来说,我使用的是 64 位 linux 机器,我可以说的是,每个字段都是对齐的,因此它位于可被其大小整除的内存地址上(对于基本类型) ,例如:
int
和float
按4对齐(必须在能被4整除的内存地址中)
char
和 bool
乘以 1(这意味着没有填充)
double
和 pointers
对齐 8
避免填充的最佳方法是将字段从大到小排列(当只有基本字段时)
当有组合字段时,我在这里解释起来有点困难,但我想你可以在论文中自己弄明白
一般取决于架构的要求。负载超过here,但可以总结如下:
Storage for the basic C datatypes on an x86 or ARM processor doesn’t
normally start at arbitrary byte addresses in memory. Rather, each
type except char has an alignment requirement; chars can start on any
byte address, but 2-byte shorts must start on an even address, 4-byte
ints or floats must start on an address divisible by 4, and 8-byte
longs or doubles must start on an address divisible by 8. Signed or
unsigned makes no difference.
在您的情况下,可能会发生以下情况:sizeof(str) = 4 (4 bytes for int) + 4 (4 bytes for int) + 1 ( 1 byte for char) + 7 (3 bytes padding + 4 bytes for int) = 20
填充在那里,因此 int
的地址是 4 字节的倍数。这个要求来自 int
是 4 个字节长的事实(我对你正在使用的架构的假设)。但这会因架构而异。
On what does it depend ? Does it depends on CPU architecture ? And does it depends on compiler also ?
CPU,至少是操作系统和编译器。
我有以下代码片段。
#include<stdio.h>
int main(){
typedef struct{
int a;
int b;
int c;
char ch1;
int d;
} str;
printf("Size: %d \n",sizeof(str));
return 0;
}
输出如下
Size: 20
我知道 structure
的大小大于 structure
的组件大小的总和,因为添加了填充以满足内存对齐约束。
我想知道如何决定必须添加多少字节的填充。它取决于什么?它取决于 CPU 体系结构吗?它也取决于编译器吗?我在这里使用 64 位 CPU 和 gcc
编译器。如果这些参数发生变化,输出将如何变化。
我知道 Whosebug 上有类似的问题,但他们没有彻底解释这个内存对齐约束。
我知道这取决于CPU架构,我想你可以在网上找到一些有趣的文章来谈论这个,wikipedia我觉得还不错。
对我来说,我使用的是 64 位 linux 机器,我可以说的是,每个字段都是对齐的,因此它位于可被其大小整除的内存地址上(对于基本类型) ,例如:
int
和float
按4对齐(必须在能被4整除的内存地址中)
char
和 bool
乘以 1(这意味着没有填充)
double
和 pointers
对齐 8
避免填充的最佳方法是将字段从大到小排列(当只有基本字段时)
当有组合字段时,我在这里解释起来有点困难,但我想你可以在论文中自己弄明白
一般取决于架构的要求。负载超过here,但可以总结如下:
Storage for the basic C datatypes on an x86 or ARM processor doesn’t normally start at arbitrary byte addresses in memory. Rather, each type except char has an alignment requirement; chars can start on any byte address, but 2-byte shorts must start on an even address, 4-byte ints or floats must start on an address divisible by 4, and 8-byte longs or doubles must start on an address divisible by 8. Signed or unsigned makes no difference.
在您的情况下,可能会发生以下情况:sizeof(str) = 4 (4 bytes for int) + 4 (4 bytes for int) + 1 ( 1 byte for char) + 7 (3 bytes padding + 4 bytes for int) = 20
填充在那里,因此 int
的地址是 4 字节的倍数。这个要求来自 int
是 4 个字节长的事实(我对你正在使用的架构的假设)。但这会因架构而异。
On what does it depend ? Does it depends on CPU architecture ? And does it depends on compiler also ?
CPU,至少是操作系统和编译器。