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. 【51nod1674】区间的价值 V2(算法效率--位运算合并优化+链表实现)

    题目链接:  51nod1674 题意:规定一个区间的价值为这个区间中所有数and起来的值与这个区间所有数or起来的值的乘积.现在l有一个 N 个数的序列,问所有n*(n+1)/2个区间的贡献的和对1 ...

  2. 【uva 10048】Audiophobia(图论--Floyd算法)

    题意:有一个N点M边的无向带权图,边权表示路径上的噪声值.有Q个询问,输出 x,y 两点间的最大噪声值最小的路径的该值.(N≤100,M≤1000,Q≤10000) 解法:N值小,且问多对点之间的路径 ...

  3. fzu2198 快来快来数一数

    Accept: 204    Submit: 627 Time Limit: 1000 mSec    Memory Limit : 65536 KB  Problem Description n个六 ...

  4. Codeforces Round #681 (Div. 2, based on VK Cup 2019-2020 - Final) D. Extreme Subtraction (贪心)

    题意:有一个长度为\(n\)的序列,可以任意取\(k(1\le k\le n)\),对序列前\(k\)项或者后\(k\)减\(1\),可以进行任意次操作,问是否可以使所有元素都变成\(0\). 题解: ...

  5. 无所不能的Embedding6 - 跨入Transformer时代~模型详解&代码实现

    上一章我们聊了聊quick-thought通过干掉decoder加快训练, CNN-LSTM用CNN作为Encoder并行计算来提速等方法,这一章看看抛开CNN和RNN,transformer是如何只 ...

  6. 要想用活Redis,Lua脚本是绕不过去的坎

    前言 Redis 当中提供了许多重要的高级特性,比如发布与订阅,Lua 脚本等.Redis 当中也提供了自增的原子命令,但是假如我们需要同时执行好几个命令的同时又想让这些命令保持原子性,该怎么办呢?这 ...

  7. hutool学习总结

    1. 为什么要学习Hutool的使用 Hutool官网 中文写的已经很清楚了 Hutool是一款强力的工具类.封装了工作开发中一些常见的功能操作.避免重复造轮子,使用它大大提高的开发效率. 2. Hu ...

  8. Django服务器布置(Ubuntu+uwsgi+nginx+Django)

    一.安装Python apt install python3 二.安装pip apt install python3-pip 三.创建目录 创建虚拟服务目录 mkdir -p /data/env 创建 ...

  9. Leetcode(7)-反转整数

    给定一个 32 位有符号整数,将整数中的数字进行反转. 示例 1: 输入: 123 输出: 321 示例 2: 输入: -123 输出: -321 示例 3: 输入: 120 输出: 21 注意: 假 ...

  10. bzoj1013球形空间产生器sphere 高斯消元(有系统差的写法

    Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧毁 ...