53 c c++ memory-alignment structure-packing
我正在使用32位机器,所以我认为内存对齐应该是4个字节.说我有结构:
typedef struct {
unsigned short v1;
unsigned short v2;
unsigned short v3;
} myStruct;
Run Code Online (Sandbox Code Playgroud)
实际大小是6个字节,我想对齐大小应该是8,但sizeof(myStruct)返回6.
但是,如果我写:
typedef struct {
unsigned short v1;
unsigned short v2;
unsigned short v3;
int i;
} myStruct;
Run Code Online (Sandbox Code Playgroud)
实际大小是10个字节,对齐是12,这次sizeof(myStruct) == 12.
有人可以解释一下有什么区别吗?
Jer*_*fin 51
至少在大多数机器上,类型只能与类型本身一样大的边界对齐[编辑:你不能真正要求任何"更多"对齐,因为你必须能够创建数组,而你无法将填充插入数组].在您的实现上,short显然是2个字节,int4个字节.
这意味着您的第一个结构与2字节边界对齐.由于所有成员各占2个字节,因此不会在它们之间插入填充.
第二个包含一个4字节的项,它与4字节边界对齐.由于它之前是6个字节,因此在v3和之间插入2个字节的填充i,在shorts中给出6个字节的数据,在两个字节的填充中,以及int总共12 个字节中的4个字节的数据.
Naw*_*waz 19
忘掉具有不同的成员,即使你写两个结构,其成员都是完全相同一样,有一个区别是,在他们声明的顺序是不同的,那么每个结构的大小可以(而且经常是)不同的.
例如,看到这个,
#include <iostream>
using namespace std;
struct A
{
char c;
char d;
int i;
};
struct B
{
char c;
int i; //note the order is different!
char d;
};
int main() {
cout << sizeof(A) << endl;
cout << sizeof(B) << endl;
}
Run Code Online (Sandbox Code Playgroud)
用它编译gcc-4.3.4,你得到这个输出:
8
12
Run Code Online (Sandbox Code Playgroud)
也就是说,即使两个结构具有相同的成员,大小也是不同的!
Ideone的代码:http://ideone.com/HGGVl
底线是标准没有讨论如何填充,因此编译器可以自由做出任何决定,你不能假设所有编译器做出同样的决定.
首先,虽然填充的细节留给了编译器,但操作系统还对对齐要求强加了一些规则。该答案假设您使用的是gcc,尽管操作系统可能会有所不同
要确定给定结构及其元素所占用的空间,可以遵循以下规则:
首先,假设该结构始终从针对所有数据类型正确对齐的地址开始。
然后对于结构中的每个条目:
sizeof(element)。char[20]数组的对齐要求与plain的要求相同char。最后,结构整体的对齐要求是其每个元素的对齐要求的最大值。
gcc将在给定元素之后插入填充,以确保下一个(如果我们在谈论最后一个元素,则为struct)正确对齐。即使将节省内存,它也不会重新排列结构中元素的顺序。
现在对齐要求本身也有些奇怪。
0x0,0x4,0x8或0xC)。请注意,这也适用于大于4个字节的类型(例如double和long double)。double只能放在以0x0或结尾的地址中0x8。唯一的例外是,long double尽管它实际上是12字节长,但仍然对齐4字节。long double是一个例外,必须对齐16字节。假设:
sizeof(unsigned short) == 2
sizeof(int) == 4
Run Code Online (Sandbox Code Playgroud)
然后我个人会使用以下(您的编译器可能会有所不同):
unsigned shorts are aligned to 2 byte boundaries
int will be aligned to 4 byte boundaries.
typedef struct
{
unsigned short v1; // 0 bytes offset
unsigned short v2; // 2 bytes offset
unsigned short v3; // 4 bytes offset
} myStruct; // End 6 bytes.
// No part is required to align tighter than 2 bytes.
// So whole structure can be 2 byte aligned.
typedef struct
{
unsigned short v1; // 0 bytes offset
unsigned short v2; // 2 bytes offset
unsigned short v3; // 4 bytes offset
/// Padding // 6-7 padding (so i is 4 byte aligned
int i; // 8 bytes offset
} myStruct; // End 12 bytes
// Whole structure needs to be 4 byte aligned.
// So that i is correctly aligned.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
36012 次 |
| 最近记录: |