![](/img/trans.png)
[英]What Is the difference between how the char datatype is stored or represented in 32bit vs 64bit in C?
[英]what is difference between structure padding in c on 32bit and 64bit architecture?
我从http://fresh2refresh.com/c-programming/c-structure-padding/读取了内存,以32位处理器中的4个字节和64位处理器中的8个字节为一组,但没有弄清楚之间的区别这两个。
struct structure2
{
int id1;
char name;
int id2;
char c;
float percentage;
};
通过32位处理器(更具体地说,它是在谈论数据总线的大小而不是寄存器的大小),这意味着一次将读取和处理32位(4字节)的数据。
现在,考虑一个int:
int a=10; //assuming 4 bytes
00000000 000000000 00000000 00001010
假设没有端序架构,则将其存储为:
------------------------------------------------------------------------
| 00001010 | 00000000 | 00000000 | 00000000 | <something_else>
-------------------------------------------------------------------------
1st byte 2nd byte 3rd byte 4th byte
\--------------------------------------------------/
|
4 bytes processed together
在这种情况下,当处理器将读取要处理的数据时,它可以一次性处理整个整数(所有4个字节在一起)(更严格地说,在1个机器周期内)
但是,请考虑以下情况:存储了相同的整数,
------------------------------------------------------------------------
|<something_else>| 00001010 | 00000000 | 00000000 | 00000000 |
-------------------------------------------------------------------------
1st byte 2nd byte 3rd byte 4th byte
\------------------------------------------------------/
|
4 bytes processed together
在这种情况下,处理器将需要2个机器周期来读取整数。
大多数体系结构始终尝试最小化CPU周期。 因此,内存中的第一种排列被许多编译器所青睐,因此会强制执行对齐要求(填充)。 因此,将4个字节的int
存储在以4s的倍数开头的地址中,将chars
存储为1s的倍数,将8个字节的doubles
存储为8s的倍数,将8个字节long long int
存储为8s的倍数,依此类推...
现在考虑你的结构
struct structure2
{
int id1; //assuming 4 byte int
char name; // 1byte
int id2; //4 byte
char c; // 1 byte
float percentage; //assuming 4 byte float
};
id1将存储在内存中的某个地址(以4的倍数开头)中,并占用4个字节。
名称将占用下一个字节。
现在,如果将id2存储在下一个字节中,则会破坏上面的对齐规则。 因此,它将保留3字节的填充并以adress开始存储,该地址是4的下一个倍数,将占用4字节。
对于c来说 ,同样的事情与name相同。 它占用下一个1字节,并保留3字节的填充。
最后百分比存储在接下来的4个字节中。
因此,结构的总大小变为20个字节 。
可以说一个更复杂的情况
struct mystructure
{
char a; //1 byte char
double b; // 8 byte double
int c; // 4 byte int
}
乍一看,这里的大小可能是20字节 (char为1字节+ 7字节为填充+ 8字节为double + 4字节为int)。
但是实际大小为24个字节 。
假设有人声明了此结构的数组
struct mystructre arr[4];
尽管arr [0]正确对齐,但此处(假定为20字节结构),但是如果仔细检查,会发现arr [1] .b未对齐。 因此,在结构的末尾添加4个字节的额外填充以使结构大小为其对齐方式的倍数。(每个结构也都有其自己的对齐要求)。
因此,总大小为24个字节。
整数,长整数等的大小由编译器决定。 编译器通常会处理处理器体系结构,但可能会选择不这样做。
同样,是否使用填充由编译器决定。 不填充称为打包 。 一些编译器具有允许打包的显式选项。
在GCC(GNU C编译器)中,您可以使用__attribute__((__packed__))
做到这一点,因此在以下代码中
struct __attribute__((__packed__)) mystructure2
{
char a;
int b;
char c;
};
由于明确请求打包结构, mystructure2的大小为6个字节。 此结构将较慢处理 。
您现在可以自己弄清楚,在64位处理器中会发生什么,或者int的大小是否不同。
该网站并没有精确地确定使用哪种64位平台,但是似乎假定使用长度对齐的整数的ILP64( int
, long
和指针为64位)平台。 这意味着int
在32位处理器上为4个字节,在64位处理器上为8个字节,并且每个字节必须以其自身长度的倍数对齐。
结果是name
和id2
之间的填充长度发生了变化(保留id2
的对齐所必需的填充)。
在32位平台上,将有3个字节的填充。 在64位平台上,将有七个。
c
和percentage
之间的填充很可能不会更改,因为浮点变量的大小不受处理器位的影响。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.