【VS开发】#pragma pack(push,1)与#pragma pack(1)的区别

摘要:
#pragmapack()函数用于取消自定义字节对齐。也就是说,对齐8个字节,然后sizeof==16。成员chara占据8个字节;如果使用#pragmapack,则样本在1字节模式下与sizeof===9对齐,这样可以节省空间。某些字段还可以使结构更易于控制。这不仅简化了编程,而且即使协议发生变化,也可以通过修改协议结构的定义来节省时间和精力。以TCP协议头为例,说明如何定义协议结构。

这是给编译器用的参数设置,有关结构体字节对齐方式设置, #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 (1)           作用:调整结构体的边界对齐,让其以一个字节对齐;<使结构体按1字节方式对齐>

#pragma  pack ()

例如:

#pragma pack(1)

struct sample
{
char a;
double b;
};

#pragma pack()

注:若不用#pragma pack(1)和#pragma pack()括起来,则sample按编译器默认方式对齐(成员中size最大的那个)。即按8字节(double)对齐,则sizeof(sample)==16.成员char a占了8个字节(其中7个是空字节);若用#pragma pack(1),则sample按1字节方式对齐sizeof(sample)==9.(无空字节),比较节省空间啦,有些场和还可使结构体更易于控制。

应用实例

在网络协议编程中,经常会处理不同协议的数据报文。一种方法是通过指针偏移的方法来得到各种信息,但这样做不仅编程复杂,而且一旦协议有变化,程序修改起来也比较麻烦。在了解了编译器对结构空间的分配原则之后,我们完全可以利用这一特性定义自己的协议结构,通过访问结构的成员来获取各种信息。这样做,不仅简化了编程,而且即使协议发生变化,我们也只需修改协议结构的定义即可,其它程序无需修改,省时省力。下面以TCP协议首部为例,说明如何定义协议结构。其协议结构定义如下: 

#pragma pack(1) // 按照1字节方式进行对齐
struct TCPHEADER 
{
     short SrcPort; 
// 16位源端口号
     short DstPort; 
// 16位目的端口号
     int SerialNo; 
// 32位序列号
     int AckNo; 
// 32位确认号
     unsigned char HaderLen : 4; 
// 4位首部长度
     unsigned char Reserved1 : 4; 
// 保留6位中的4位
     unsigned char Reserved2 : 2; 
// 保留6位中的2位
     unsigned char URG : 1;
     unsigned char ACK : 1;
     unsigned char PSH : 1;
     unsigned char RST : 1;
     unsigned char SYN : 1;
     unsigned char FIN : 1;
     short WindowSize; 
// 16位窗口大小
     short TcpChkSum; 
// 16位TCP检验和
     short UrgentPointer; 
// 16位紧急指针
}; 
#pragma pack()

免责声明:文章转载自《【VS开发】#pragma pack(push,1)与#pragma pack(1)的区别》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Linux (三)VC++ 设置软件开机自启动的方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

数据对齐

许多计算机系统对数据类型的合法地址做了一些限制,要求某种数据类型对象的地址必须是某个值K(2,4,8)的倍数,这种堆积限制简化形成了处理器和存储器系统之间接口的硬件设计,总之就是为了方便高效的读取数据,于是就有了数据对齐。 struct S1 { char k; double i; char c; }; Sizeof(S1)的...

内存字节对齐解释(转)

  一、 什么是对齐,以及为什么要对齐:1. 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。2. 对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同...

内表、结构赋值转换规则

内表转换规则... 57 C语言中的结构对齐... 57 ABAP结构体对齐... 58 结构体相互赋值转换规则... 59 MOVE-CORRESPONDING(结构体赋值)... 62 内表转换规则 内表只能被转换成其他内表,而不能转换成结构或基本类型。 一个内表能否转换成其他内表与内表中的现有数据行没有关系,而是看两个内表的行结构是否可转换...

语言基础(12):struct/union字节对齐

1、什么是字节对齐 在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题。从理论上讲,对于任何变量的访问都可以从任何地址开始访问,但实际上访问特定类型的变量只能在特定的地址访问,这就需要各个变量在空间上按一定的规则排列, 而不是简单地顺序排列,这就是内存对齐。 2、为什么要字节对齐 某...

字节对齐《c和指针》笔记包含位域结构体的内存对齐(32bit,GCC)

最近使用开发的过程中出现了一个小问题,顺便记录一下原因和方法--字节对齐     C99划定int、unsigned   int和bool可以作为位域类型。但编译器几乎都对此作了扩展,答应其它类型类型的存在。     如果结构体中含有位域(bit-field),总结规则如下:(以下代码在x86 32bit系统上测试,gcc 4.1.2)     1) 如果...

C++ 常见崩溃问题分析

一、前言 从事自动化测试平台开发的编程实践中,遭遇了几个程序崩溃问题,解决它们颇费了不少心思,解决过程中的曲折和彻夜的辗转反侧却历历在目,一直寻思写点东西,为这段难忘的经历留点纪念,总结惨痛的教训带来的经验,以期通过自己的经历为他人和自己带来福祉:写出更高质量的程序; 由于 C 和 C++ 这两种语言血缘非常近,文本亦对 C 编程语言有借鉴作用; 二、C+...