1、字节对齐(内存相关)

  现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
  各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该int数据。显然在读取效率上下降很多。这也是空间和时间的博弈。

2、#pragma pack(x)-结构体对齐规则

  字节对齐:(在 .h 头文件中为#pragma pack(x)) (x = 1 2 4 ...)
  结构体中各个成员按照它们被声明的顺序在内存中顺序存储。

  1)将结构体内所有数据成员的长度值相加,记为sum_a; 
  2)将各数据成员内存对齐,按各自对齐模数而填充的字节数累加到和sum_a上,记为sum_b。对齐模数是【该数据成员所占内存】与【#pragma pack指定的数值】中的较小者。

  3)将和sum_b向结构体模数对齐,该模数是【#pragma pack指定的数值】、【未指定#pragma pack时,系统默认的对齐模数8字节】和【结构体内部最大的基本数据类型成员】长度中数值较小者。结构体的长度应该是该模数的整数倍。
以32bit编译器为例:
 1 #pragma pack(4)
2 struct Test1
3 {
4 char c;
5 short sh;
6 int a;
7 float f;
8 int *p;
9 char *s;
10 double d;
11 };

  总共占28Bytes。 c的偏移量为0,占1个Byte。sh占2个Byte,它的对齐模数是2(2<4,取小者),存放起始地址应该是2的整数倍,因此c后填充1个空字符,sh的起始地址是2。a占4个Byte,对齐模数是4,因此接在sh后存放即可,偏移量为4。f占4个字节,对齐模数是4,存放地址是4的整数倍,起始地址是8。p,s的起始地址分别是12,16。d占8个字节,对齐模数是4(4<8),d从偏移地址为20处存放。存放后结构体占28个字节,是4的整数倍不用补空字符。

#progma pack(x)说明的更多相关文章

  1. IOS学习之路--OC的基础知识

    1.项目经验 2.基础问题 3.指南认识 4.解决思路 ios开发三大块: 1.Oc基础 2.CocoaTouch框架 3.Xcode使用 -------------------- CocoaTouc ...

  2. C语言:内存字节对齐详解[转载]

    一.什么是对齐,以及为什么要对齐: 1. 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问, ...

  3. iOS求职之OC面试题

    1.Objective-C的类可以多重继承么?可以采用多个协议么? 答:不可以多重继承,可以采用多个协议. 2.#import和#include的区别是什么?#import<> 跟 #im ...

  4. 第13章 Windows内存体系结构

    13.1 Windows的虚拟地址空间安排 13.1.1虚拟地址空间的分区(即虚拟地址空间布局) 进程的地址空间划分 分区 x86 32位 Windows 3GB用户模式下的x86 32位Window ...

  5. C++ 中常见预定义宏的使用

    http://blog.csdn.net/hgl868/article/details/7058906 替代字符串: #define DOWNLOAD_IMAGE_LOG /var/log/png.l ...

  6. C++ 中宏的使用 --来自:http://blog.csdn.net/hgl868/article/details/7058906

    宏在代码中的使用实例: g_RunLog2("Middleware client for Linux, build:%s %s", __DATE__, __TIME__); 下面详 ...

  7. C语言中内存对齐方式

    一.什么是对齐,以及为什么要对齐: 1. 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问, ...

  8. (转载)C语言预处理

    C程序的源代码中可包括各种编译指令,这些指令称为预处理命令.虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境.本节将介绍如何应用预处理程序和注释简化程序开发过程,并提高程序的可读性.ANS ...

  9. iOS谋职之OC面试题

    iOS谋职之OC面试题 iOS求职之OC面试题 IOS求职之OC面试题 1.Objective-C的类可以多重继承么?可以采用多个协议么? 答:不可以多重继承,可以采用多个协议. 2.#import和 ...

随机推荐

  1. 【洛谷 p3381】模板-最小费用最大流(图论)

    题目:给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 解法:在Dinic的基础下做spfa算法. 1 #include<cst ...

  2. hdu1828 Picture(线段树+扫描线+矩形周长)

    看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积))  解法一·:两次扫描线 如图我们可以 ...

  3. POJ1142 Smith Numbers 暴力+分解质因子

    题意:题目定义了一个史密斯数,这个数的定义是:一个合数的各个位置上加起来的和等于它的素因数所有位置上的数字加起来的和.比如: 4937775=3∗5∗5∗658374+9+3+7+7+7+5=3+5+ ...

  4. XV6学习(16)Lab net: Network stack

    最后一个实验了,代码在Github上. 这一个实验其实挺简单的,就是要实现网卡的e1000_transmit和e1000_recv函数.不过看以前的实验好像还要实现上层socket相关的代码,今年就只 ...

  5. Seq2Seq原理详解

    一.Seq2Seq简介 seq2seq 是一个Encoder–Decoder 结构的网络,它的输入是一个序列,输出也是一个序列.Encoder 中将一个可变长度的信号序列变为固定长度的向量表达,Dec ...

  6. Go语言中时间轮的实现

    最近在工作中有一个需求,简单来说就是在短时间内会创建上百万个定时任务,创建的时候会将对应的金额相加,防止超售,需要过半个小时再去核对数据,如果数据对不上就需要将加上的金额再减回去. 这个需求如果用Go ...

  7. github 无法访问

    描述: 1. ping 丢失 100% 2. git 失败 Failed to connect to github.com port 443: Timed out 3.打开网站 超时 解决: http ...

  8. codeforces 3D (非原创)

    D. Least Cost Bracket Sequence time limit per test 1 second memory limit per test 64 megabytes input ...

  9. Springboot如何启用文件上传功能

    网上的文章在写 "springboot文件上传" 时,都让你加上模版引擎,我只想说,我用不上,加模版引擎,你是觉得我脑子坏了,还是觉得我拿不动刀了. springboot如何启用文 ...

  10. 微信小程序开发抖音去水印功能

    之前找了很多抖音去水印的工具全是广告,所以索性自己写了一个,提供给大家免费试用以下是微信小程序的二维码 使用教程: 1.打开微信搜索小程序:沸点软件技术服务 2.打开沸点软件技术服务小程序 3.去抖音 ...