结构体对齐方式浅析

这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式。

#pragma pack (n)             作用:C编译器将按照n个字节对齐。
#pragma pack ()               作用:取消自定义字节对齐方式。


#pragma  pack (push,1)     作用:是指把原来对齐方式设置压栈,并设新的对齐方式设置为一个字节对齐

#pragma pack(pop)            作用:恢复对齐状态

因此可见,加入push和pop可以使对齐恢复到原来状态,而不是编译器默认,可以说后者更优,但是很多时候两者差别不大

#pragma  pack(push)//保存对齐方式

#pragma  pack(4) //以4个字节对齐

二者合起来相当于#pragma  pack (push,4) 的效果

如果结构体不用#pragma  pack (push,n) 和#pragma pack(pop)括起来,编译器将按默认的对齐方式对齐。

以下是示例:

 #include "stdafx.h"
#include <map>
#include "iostream"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{

 struct sample
  {
      int a;
      double b;
      char c;
   };
 long lLen = sizeof(sample);
 long lLen1 = sizeof(int);
 long lLen2 = sizeof(double);
 long lLen3 = sizeof(char);
 cout<<"sample:"<<lLen<<"\t"<<"a:"<<lLen1<<"\t"<<"b:"<<lLen2<<"\t"<<"c:"<<lLen3<<endl;
 
 return 0;
}

运行的结果:

 
按结构体中size的最大者来对齐,最大是double型8字节,而int型和char型都占了8字节,剩下的是空字节。
 
如果添加了#pragma  pack (push,n) 和#pragma pack(pop)结构体将按指定字节对齐 

#include "stdafx.h"
#include <map>
#include "iostream"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{

 

#pragma pack(push, 4)  //按4字节对齐

 struct sample
  {
      int a;
      double b;
      char c;
   };

#pragma pack(pop)


 long lLen = sizeof(sample);
 long lLen1 = sizeof(int);
 long lLen2 = sizeof(double);
 long lLen3 = sizeof(char);
 cout<<"sample:"<<lLen<<"\t"<<"a:"<<lLen1<<"\t"<<"b:"<<lLen2<<"\t"<<"c:"<<lLen3<<endl;
 
 return 0;
}

 

按1字节对齐

#pragma pack(push, 1)  //按1字节对齐

  struct sample
  {
      int a;
      double b;
      char c;
   };

#pragma pack(pop)

由此可见按指定对齐方式对齐比较节省空间。

注意:根据常规数据类型所占的字节数一般为1、2、4、8和16字节数,因此,对齐方式设置的值一般为以上几个值,否则报错!

posted @ 2015-11-27 17:44  时光回眸  阅读(247)  评论(0编辑  收藏  举报