内存对齐和#pragma pack(n)

来源:互联网 发布:魔兽争霸3 1.24e mac 编辑:程序博客网 时间:2024/05/21 17:43

#pragma pack(n)的意思是以n个字节作为内存对齐的标准。

内存对齐的引入是为了减少内存访问次数。访问内存不对齐的数据需要访问两次内存,而访问内存对齐的数据则只需1次。很明显,这样程序的性能就提高了不少,但是也相对牺牲了一些空间作为代价。有些小技巧可以使牺牲的空间减到最少,即定义结构体时可以将类型按字节大小从小到大地定义。在VC++中一般都默认是以8个字节(#pragma pack(8))为内存对齐标准。

那么怎样才能算是内存对齐呢?当前面所有的类型字节之和(比如char、int),是当前类型的整数倍,那么,当前类型是内存对齐的。但从整个结构体来说,它还必须符合整个结构体是较小类型或是默认的内存对齐标准的整数倍。

举个例子:

         struct foo
         {
           char c1;
           int i;
           short s;
           char c2;
           char c3;
          };

 

下面代码输出它们的相对位移地址, 

        struct foo a;
    printf("c1 %p, s %p, c2 %p, i %p, c3 %p/n",
        (unsigned int)(void*)&a.c1 - (unsigned int)(void*)&a,
        (unsigned int)(void*)&a.s - (unsigned int)(void*)&a,
        (unsigned int)(void*)&a.c2 - (unsigned int)(void*)&a,
        (unsigned int)(void*)&a.i - (unsigned int)(void*)&a,
  (unsigned int)(void*)&a.c3 - (unsigned int)(void*)&a);

结果为:

c1 00000000,  i 00000004, s 00000008, c2 0000000A,c3 0000000B
12

而对于

         struct foo
         {
           char c1;
           int i;
           short s;
           char c2;
           char c3;
           char c4;
          };

则结果为:
c1 00000000, i 00000004, s 00000008, c2 0000000A, c3 0000000B,c4 0000000C
16

若用0表示数据是填补,则前者可以表示为

1000
1111
11

而后者可表示为

1000
1111
11


1000

这是因为从整个结构体来说,它还必须符合整个结构体是较小类型或是默认的内存对齐标准的整数倍。

原创粉丝点击