#pragma pack(n) 的作用
在C语言中,结构是一种复合数据类型,其构成元素既可以是基本数据类型(如int、long、float等)的变量,也可以是一些复合数据类型(如数组、结构、联合等)的数据单元。在结构中,编译器为结构的每个成员按其自然对界(alignment)条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。
例如,下面的结构各成员空间分配情况:
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... 第一种方式较为常见。
下面有一道在 CSDN论坛 上讨论火热的题:
Intel和微软等公司同时出现的面试题
#pragma pack(8)
struct s1{
short a;
long b;
};
struct s2{
char c;
s1 d;
long long e;
};
#pragma pack()
问
1.sizeof(s2) = ?
2.s2的c后面空了几个字节接着是d?
结果如下:
sizeof(S2)结果为24.
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐.
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节.
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8;
S2 中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是 按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节 的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节.
a b
S1的内存布局:11**,1111,
c S1.a S1.b d
S2的内存布局:1***,11**,1111,****11111111
这里有三点很重要:
1.每个成员分别按自己的方式对齐,并能最小化长度
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐
补充一下,对于数组,比如:
char a[3];这种,它的对齐方式和分别写3个char是一样的.也就是说它还是按1个字节对齐.
如果写: typedef char Array3[3];
Array3这种类型的对齐方式还是按1个字节对齐,而不是按它的长度.
不论类型是什么,对齐的边界一定是1,2,4,8,16,32,64....中的一个.
相关文章:

LoadRunner设置检查点的几种方法介绍
LoadRunner设置检查点的几种方法介绍 发布时间: 2011-5-03 11:53 作者: 一米阳光做测试 来源: 51Testing软件测试网采编 字体: 小 中 大 | 上一篇 下一篇 | 打印 | 我要投稿 3、将脚本切换回代码界面, 在光标闪烁的上行,添加如下的代码&…

Python 爬虫利器 Selenium 从入门到进阶
作者 | 俊欣来源 | 关于数据分析与可视化今天小编就来讲讲selenium,我们大致会讲这些内容selenium简介与安装页面元素的定位浏览器的控制鼠标的控制键盘的控制设置元素的等待获取cookies调用JavaScriptselenium进阶selenium的简介与安装selenium是最广泛使用的开源W…

获取下个月的今天
/* 获取下个月的今天如果 $date 2018-1-31 二月没有31号 则获取二月份的最后一天 返回值为2018-2-28如果 $date 2018-1-15 返回值为2018-2-15 -- psw-- */function getNextMonthDays($date){$firstday date(Y-m-01, strtotime($date));$lastday strtotime("$firstday …

C语言的sizeof和strlen
strlen是函数,而sizeof是算符。strlen需要进行一次函数调用,而对于sizeof而言,因为缓冲区已经用已知字符串进行了初始化,起长度是固定的,所以sizeof在编译时计算缓冲区的长度。因为sizeof()测试的是数组的长度。而strl…

机器人 Ameca「苏醒」瞬间逼真到令人恐惧,网友纷纷惊叹……
整理 | 禾木木 出品 | AI科技大本营(ID:rgznai100) 近日,国内外网友都被一段机器人「苏醒」的视频惊讶到。 视频开始时,机器人似乎已经睡着,眼睛闭着,头部略微向下倾斜。随着肩膀的伸展,机器…

linux源码包卸载方式
linux源码包软件的安装与卸载3人收藏此文章,我要收藏 发表于1年前 , 已有593次阅读 共0个评论Linux软件安装与卸载(源码包形式):一般情况下linux程序的发布不能像windows那样,直接打包成一个setup.exe文件,然用户安装 …
在实践中我遇到stompjs, websocket和nginx的问题与总结
阅读原文:https://wdd.js.org/stomp-over... 1. AWS EC2 不支持WebSocket 直达解决方案 英文版 简单说一下思路:WebSocket底层基于TCP协议的,如果你的服务器基于HTTP协议暴露80端口,那WebSocket肯定无法连接。你只要将HTTP协议修改…

C语言memset函数详解(Linux下和windows下的差异)
memest原型 (please type "man memset" in your shell) void *memset(void *s, int c, size_t n); memset:作用是在一段内存块中填充某个给定的值,它对较大的结构体或数组进行清零操作的一种最快方法。 #include <stdio.h>#include <string.…

Oracle 工程师离职并回踩:MySQL 糟糕透顶,强烈推荐 PostgreSQL
整理 | 祝涛 出品 | CSDN(ID:CSDNnews)如果你即将离职,你会做什么?抨击自己付出了五年心血的技术——这是Oracle公司前首席软件工程师、MySQL优化器团队成员Steinar Gunderson的选择。这位工程师现已在Chrome团队…

ORA-01109:数据库未打开(解决)
SQL> startup mountORA-01081: 无法启动已在运行的 ORACLE - 请首先关闭它SQL> shutdown immediateORA-01109: 数据库未打开 已经卸载数据库。ORACLE 例程已经关闭。SQL> startup mountORACLE 例程已经启动。 Total System Global Area 612368384 bytesFixed Size 125…

[洛谷P1317]低洼地
题目大意:一组数,分别表示地平线的高度变化。高度值为整数,相邻高度用直线连接。找出并统计有多少个可能积水的低洼地?(首尾都为0) 题解:求出其中都多少个不严格下降子段和不严格上升子段所夹的…

Linux环境编程--多线程
本文作者: 姚继锋 (2001-08-11 09:05:00) 时隔多年 原文地址已经无从查。。。 居然是2001年就写了 今天看来对初学者还是很有参考意义 所以特转给大家 本人在原文基础上适当修改 1 引言 线程(thread)技术早在60年代就被提出,但真正应…

Python 到底该怎么学才好?你关心的答案来了
相对于Android、IOS等技术,Python有着更为广阔的应用领域,例如前后端、AI、数据分析、爬虫、自动化、游戏开发等几乎所有领域都有它的应用。但也正因为如此,很多新人在学完Python基础后,根本不知道该选择什么方向深造,…

9513 防空洞
时间限制:1000MS 内存限制:65535K提交次数:104 通过次数:24 题型: 编程题 语言: G;GCC Description 有一天,dragon123偷偷地拿锄头在学校里挖开了一个尘封已久的防空洞。他在这个防空洞里面找到许多贵重的东西:一些石头和一些液体。dragon123知道&…

学习Mybatis与mysql数据库的示例笔记
目录结构: pom.xml文件 1 <?xml version"1.0" encoding"UTF-8"?>2 <project xmlns"http://maven.apache.org/POM/4.0.0"3 xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"4 xsi:schem…

Linux环境编程--进程通信
实验内容 编写程序实现进程的管道通信。用系统调用pipe( )建立一管道,二个子进程P1和P2分别向管道各写一句话:Child 1 is sending a message!Child 2 is sending a message! 父进程从管道中读出二个来自子进程的信息并显示(要求先接收P1&…

你的编程能力从什么时候开始突飞猛进的?
如果提到程序员,很多人的印象是:呆板、木讷、不懂浪漫。如果提到代码,很多人的印象是:枯燥、繁琐、很难理解。但其实程序员的浪漫是普通人想象不到的,有一个网友为了追女生,以自己和女生为主角写了一个战棋…

超级 App 手机百度云端架构设计与个性化推荐
2015 年 6 月 28 日下午,百度与 InfoQ 携手举办了手机百度“云和端技术实践”沙龙活动。这是手机百度首次公开超级 App 背后的技术知识。活动分云端和客户端技术两个会场同时举办,吸引了众多技术爱好者前来学习交流。现场人数爆满,气氛热烈。…
Scala和范畴论 -- 对Monad的一点认识
背景 所有一切的开始都是因为这句话:一个单子(Monad)说白了不过就是自函子范畴上的一个幺半群而已,有什么难以理解的。第一次看到这句话是在这篇文章:程序语言简史(伪)。这句话出自Haskell大神Philip Wadler࿰…

Linux环境编程--linux中的perror、exit、_exit、wait 和 waitpid
perror:#include<stdio.h> #include<stdlib.h>定义函数 void perror(const char *s); perror ("open_port");函数说明 perror ( )用 来 将 上 一 个 函 数 发 生 错 误 的 原 因 输 出 到标 准 错误 (stderr) 。参数 s 所指的字符…

DeepMind 打造 AI 游戏系统,可以玩扑克、国际象棋、围棋等,战斗力爆表
编译 | 禾木木 出品 | AI科技大本营(ID:rgznai100) 谷歌母公司 Alphabet 的人工智能实验室 DeepMind 长期以来一直投资于游戏人工智能系统。实验室的理念是,游戏虽然缺乏明显的商业应用,但却是认知和推理能力的独特相关挑战。这使…

WPF-动态加载
添加一个UserControl,命名为BusyIndicator,view为空,在其.cs文件中定义一个类 1 /// <summary> 2 /// 动态实体 3 /// </summary> 4 public class AnimationObject 5 { 6 publ…

ORA-06502 when awr report produce
最近在生成一套系统的AWR报告时出现了如下报错:ORA-06502: PL/SQL: numeric or value error: character string buffer too small,然后生成AWR报告的过程就终止了,查看生成的AWR报告,发现报告时不完整的,AWR报告到Comp…

进程间通信学习小结(共享内存)
要使用共享内存,应该有如下步骤:1.开辟一块共享内存 shmget()2.允许本进程使用共某块共享内存 shmat()3.写入/读出4.禁止本进程使用这块共享内存 shmdt()5.删除这块共享内存 shmctl()或者命令行下ipcrm 共享内存可以说是最有用的进程间通信方式ÿ…

[ObjectiveC]NSDATA, NSDICTIONARY, NSSTRING互转
2019独角兽企业重金招聘Python工程师标准>>> NSDATA-->NSDICTIONARY NSDictionary *dict [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]; NSDICTIONARY-->NSDATA NSData *data [NSJSONSerialization dat…

如流智会2021:技术结合场景 让企业知识懂员工
12月10日,“如流智会2021智能进化”在京举行,学界专家业界大咖云集荟聚,共商企业智能化转型之道。会上,百度集团副总裁、百度集团首席信息官(CIO)李莹表示:“智能经济时代,智能组织是…

WSFC 仲裁模型选择
今天我们再来详细讨论下关于WSFC的仲裁模型,主要仲裁模型的优缺点,应该如何去思考选择最佳合适方案WSFC引入仲裁,主要有两个目的跟踪群集当前运作票数是否符合仲裁模型协定,如果低于最少允许节点,则决定关闭群集&#…

关于进程间通信的学习心得
进程:进程是指独立地址空间的指令序列进程的五种状态:新建,就绪,运行,睡眠,僵死进程间通信:是不同进程之间进行一些"接触",这种接触有简单,有复杂。机制不同&a…

Go modules基础精进,六大核心概念全解析(上)
Go 语言做开发时,路径是如何定义的?Go Mudules又为此带来了哪些改变?本文将会全面介绍Go Modules六大核心概念,包括了设计理念与兼容性原则等,掌握这些技术点对于管理和维护Go 模块有重要价值。 在Go Modules 的前世今…

PARAMETERS 指令
语法: PARAMETERS <p> [DEFAULT <f>] [LOWER CASE] [OBLIGATORY] [AS CHECKBOX] [RADIOBUTTON GROUP <rad>] 实例: PARAMETERS: NAME(8), AGE TYPE I, BIRTH TYPE D. OBLIGATORY:强制要求输入, 屏幕上会出現一个“√” , 使用者必须要输入才可。 AS C…