读书人

内存对齐有关问题

发布时间: 2012-10-18 13:46:55 作者: rapoo

内存对齐问题
之前不知道有这么回事 = =! 汗
看见一书,
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个字节 没有字节浪费。

读书人网 >C语言

热点推荐