内存对齐问题
之前不知道有这么回事 = =! 汗
看见一书,
struct foo{
char c1;
short s;
char c2;
int i;
};
其中c1 s c2 i 相对于foo的起始地址的偏移量分别为多少?
如果改成
struct foo2{
char c1;
char c2;
short s;
int i;
};
其中c1 s c2 i 相对于foo的起始地址的偏移量分别为多少?
[解决办法]
#pragma pack( [ n] )
Specifies packing alignment for structure and union members. Whereas the packing alignment of structures and unions is set for an entire translation unit by the /Zp option, the packing alignment is set at the data-declaration level by the pack pragma. The pragma takes effect at the first structure or union declaration after the pragma is seen; the pragma has no effect on definitions.
When you use #pragma pack(n), where n is 1, 2, 4, 8, or 16, each structure member after the first is stored on the smaller member type or n-byte boundaries. If you use #pragma pack without an argument, structure members are packed to the value specified by /Zp. The default /Zp packing size is /Zp8.
[解决办法]
#pragma pack(n)
1 Aligns structure members on 1-byte boundaries, or on their natural alignment boundary, whichever is less.
2 Aligns structure members on 2-byte boundaries, or on their natural alignment boundary, whichever is less.
4 Aligns structure members on 4-byte boundaries, or on their natural alignment boundary, whichever is less.
8 Aligns structure members on 8-byte boundaries, or on their natural alignment boundary, whichever is less.
16 Aligns structure members on 16-byte boundaries, or on their natural alignment boundary, whichever is less.
- C/C++ code
struct foo1_pack0 { char c1; short s; char c2; int i;};struct foo2_pack0 { char c1; char c2; short s; int i;};#if defined(_MSC_VER)#pragma pack(push,1)#elif defined(__IBMC__)#pragma pack(1)#else#pragma pack(1)#endifstruct foo1_pack1 { char c1; short s; char c2; int i;};struct foo2_pack1 { char c1; char c2; short s; int i;};#pragma pack(pop)#if defined(_MSC_VER)#pragma pack(push,2)#elif defined(__IBMC__)#pragma pack(2)#else#pragma pack(2)#endifstruct foo1_pack2 { char c1; short s; char c2; int i;};struct foo2_pack2 { char c1; char c2; short s; int i;};#pragma pack(pop)#if defined(_MSC_VER)#pragma pack(push,4)#elif defined(__IBMC__)#pragma pack(4)#else#pragma pack(4)#endifstruct foo1_pack4 { char c1; short s; char c2; int i;};struct foo2_pack4 { char c1; char c2; short s; int i;};#pragma pack(pop)#include <stddef.h>int main(int argc, char *argv[]){ printf("%s: %ld %ld %ld %ld\n", "foo1_pack0", offsetof(struct foo1_pack0, c1), offsetof(struct foo1_pack0, c2), offsetof(struct foo1_pack0, s), offsetof(struct foo1_pack0, i)); printf("%s: %ld %ld %ld %ld\n", "foo2_pack0", offsetof(struct foo2_pack0, c1), offsetof(struct foo2_pack0, c2), offsetof(struct foo2_pack0, s), offsetof(struct foo2_pack0, i)); printf("%s: %ld %ld %ld %ld\n", "foo1_pack1", offsetof(struct foo1_pack1, c1), offsetof(struct foo1_pack1, c2), offsetof(struct foo1_pack1, s), offsetof(struct foo1_pack1, i)); printf("%s: %ld %ld %ld %ld\n", "foo2_pack1", offsetof(struct foo2_pack1, c1), offsetof(struct foo2_pack1, c2), offsetof(struct foo2_pack1, s), offsetof(struct foo2_pack1, i)); printf("%s: %ld %ld %ld %ld\n", "foo1_pack2", offsetof(struct foo1_pack2, c1), offsetof(struct foo1_pack2, c2), offsetof(struct foo1_pack2, s), offsetof(struct foo1_pack2, i)); printf("%s: %ld %ld %ld %ld\n", "foo2_pack2", offsetof(struct foo2_pack2, c1), offsetof(struct foo2_pack2, c2), offsetof(struct foo2_pack2, s), offsetof(struct foo2_pack2, i)); printf("%s: %ld %ld %ld %ld\n", "foo1_pack4", offsetof(struct foo1_pack4, c1), offsetof(struct foo1_pack4, c2), offsetof(struct foo1_pack4, s), offsetof(struct foo1_pack4, i)); printf("%s: %ld %ld %ld %ld\n", "foo2_pack4", offsetof(struct foo2_pack4, c1), offsetof(struct foo2_pack4, c2), offsetof(struct foo2_pack4, s), offsetof(struct foo2_pack4, i)); return 0;}
[解决办法]
结构体 偏移量 所占字节数
struct foo{
char c1; 0 1
short s; 2 2
char c2; 4 4
int i; 8 4
}; 总大小:12个字节 C1和s之间浪费一个字节,C2和i之间浪费了3个字节
struct foo2{
char c1; 0 1
char c2; 1 1
short s; 2 2
int i; 4 4
}; 总大小:8个字节 没有字节浪费。