当前位置: 首页 > news >正文

转载: #pragma pack(push,1) #pragma pack(pop)

1 引子

      在程序中,有的时候我们定义结构体的时候,要用#pragma pack(push,1) & #pragma pack(pop)类似代码将结构体包起来。

一般形式如下:

#pragma pack(push,1);

struct A

{

 

} ;

#pragma pack(pop);

这么做有什么目的呢?

 注:下列内容来自网络。

2 #pragma pack简介

#pragma pack是指定数据在内存中的对齐方式,

 

在 C语言中,结构是一种复合数据类型,其构成元素既可以是基本数据类型(如int、long、float等)的变量,也可以是一些复合数据类型(如数组、结 构、联合等)的数据单元。在结构中,编译器为结构的每个成员按其自然对界(alignment)条件分配空间。各个成员按照它们被声明的顺序在内存中顺序 存储,第一个成员的地址和整个结构的地址相同。

例 1:

struct sample
{
char a;
double b;
};

若 不用#pragma pack(1)和#pragma pack()括起来,则sample按编译器默认方式对齐(成员中size最大的那个)。即按8字节(double)对齐,则 sizeof(sample)==16.成员char a占了8个字节(其中7个是空字节)

若用#pragma pack(1),则sample按1字节方式对齐sizeof(sample)==9.(无空字节)

 

例 2:下面的结构各成员空间分配情况:
struct test
{
     char x1;
     short x2;
     float x3;
     char x4;
};
     结构的第一个成员x1,其偏移地址为0,占据了第1个字节。第二个成员x2为short类型,其起始地址必须2字节对界,因此,编译器在x2和x1之间填 充了一个空字节。结构的第三个成员x3和第四个成员x4恰好落在其自然对界地址上,在它们前面不需要额外的填充字节。在test结构中,成员x3要求4字 节对界,是该结构所有成员中要求的最大对界单元,因而test结构的自然对界条件为4字节,编译器在成员x4后面填充了3个空字节。整个结构所占据空间为 12字节。更改C编译器的缺省字节对齐方式
     在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间。一般地,可以通过下面的方法来改变缺省的对界条件:
  · 使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。
     · 使用伪指令#pragma pack (),取消自定义字节对齐方式。

     另外,还有如下的一种方式:
     · __attribute((aligned (n))),让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。
     · __attribute__ ((packed)),取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐。

以上的n = 1, 2, 4, 8, 16... 第一种方式较为常见。

3 应用实例

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

 

转自:http://blog.csdn.net/mannhello/article/details/5384431

转载于:https://www.cnblogs.com/xixi-/p/5492376.html

相关文章:

  • 【转】Android 防破解技术简介
  • Go 环境变量
  • 使用LocalBroadcastManager
  • exif信息对照
  • 前端学习笔记--9/5~13/5 Ajax, jQuery
  • 【COCOS2DX-LUA 脚本开发之二】LUA语言基础
  • OC语言大总结(下)
  • Lucene5学习之使用MMSeg4j分词器
  • PostgreSQL 9.6 攻克金融级多副本可靠性问题
  • 1.3 中国云创行业地图
  • cacti系列之安装篇 LNMP+cacti+spine (一)
  • 华为S5700实现两个VLAN间不通信的ACL策略
  • Appstore热搜的五款外包应用!
  • Ubuntu安装配置串口通讯工具minicomcutecom
  • 关于前端复用的实践
  • ES6指北【2】—— 箭头函数
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • Angular Elements 及其运作原理
  • ES6之路之模块详解
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • mongodb--安装和初步使用教程
  • REST架构的思考
  • Spring声明式事务管理之一:五大属性分析
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • 使用parted解决大于2T的磁盘分区
  • 数据仓库的几种建模方法
  • 微信小程序设置上一页数据
  • 智能网联汽车信息安全
  • 《码出高效》学习笔记与书中错误记录
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • 浅谈sql中的in与not in,exists与not exists的区别
  • 如何在招聘中考核.NET架构师
  • ​iOS实时查看App运行日志
  • # 飞书APP集成平台-数字化落地
  • #162 (Div. 2)
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (2)MFC+openGL单文档框架glFrame
  • (Note)C++中的继承方式
  • (NSDate) 时间 (time )比较
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (超详细)语音信号处理之特征提取
  • (二十四)Flask之flask-session组件
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • (循环依赖问题)学习spring的第九天
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • .net Application的目录
  • .net core Swagger 过滤部分Api
  • .NET MVC 验证码
  • .Net 代码性能 - (1)
  • .NET 事件模型教程(二)
  • .net 微服务 服务保护 自动重试 Polly
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?
  • @Autowired多个相同类型bean装配问题