1、什么是内存对齐?

下面先来看一个例子:

#include <stdio.h>
int main()
{struct Text1{char c1;short s;                          char c2;int i;};struct Text2{char c1;char c2;short s;int i;};printf("%ld\n",sizeof(struct Text1));        //12    GCC下编译的结果printf("%ld\n",sizeof(struct Text2));        //8return 0;
}

解析:
在windows系统32位平台上:
int占4个字节
char占1个字节
float占4个字节
double占8个字节
1、首先确定对齐参数:对齐参数是由变量的自身对齐参数和编译器默认的对齐参数一起确定的!它是结构体中所有变量的自身对齐参数的最大值和系统默认参数中较小的那一个!(含有double类型的除外,原因如下!)而变量的自身对齐参数是由CPU字节长度(32位为4)和变量本身的字节长度中的较小的那一个(即变量的自身对齐参数<=4),所以本题中的对齐参数为4!
2、知道了对齐参数为4,即知道了分配单位就是4!

这里需注意的是:
VC和GCC默认的都是4字节对齐,编程中可以使用#pragma pack(n)指定对齐模数。出现以上差异的原因在于,VC和GCC中对于double类型的对齐方式不同。
Win32平台下的微软VC编译器在默认情况下采用如下的对齐规则: 任何基本数据类型T的对齐模数就是T的大小,即sizeof(T)。比如对于double类型(8字节),就要求该类型数据的地址总是8的倍数,而char类型数据(1字节)则可以从任何一个地址开始。
Linux下的GCC奉行的是另外一套规则:任何2字节大小(包括单字节吗?)的数据类型(比如short)的对齐模数是2,而其它所有超过2字节的数据类型(比如long,double)都以4为对齐模数!

#prama pack()能改变编译器的默认对齐方式!例如

#pragma pack(n)                     //编译器将按照n字节对齐#pragma pack()                       //编译器将取消自定义字节对齐方式

在#pragma pack(n)和#pragma pack()之间的代码按n字节对齐! 此为强制对齐!

2、为什么会有内存对齐?

字、双字和四字在自然边界上不需要在内存中对齐。对字、双字和四字来说,自然边界分别是偶数地址、可以被4整除的地址和可以被8整除的地址。无论如何,为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要做两次内存访问;然而,对齐的内存访问仅需要进行一次访问。

一个字或双字操作数跨越了4字节边界,或者一个四字操作数跨越了8字节边界,被认为是未对齐的,从而需要两次总线周期来访问内存。一个字起始地址是奇数但却没有跨越字边界被认为是对齐的,能够在一个总线周期中被访问。某些操作双四字的指令需要内存操作数在自然边界上对齐。如果操作数没有对齐,这些指令将会产生一个通用保护异常。双四字的自然边界是能够被16整除的地址。其他的操作双四字的指令允许未对齐的访问(不会产生通用保护异常),然而,需要额外的内存总线周期来访问中未对齐的数据。

补充:
自然对齐指的是将对应变量类型存入对应地址值的内存空间,即数据要根据其数据类型存放到以其数据类型为倍数的地址处。例如char类型占1个字节空间,1的倍数是所有数,因此可以放置在任何允许地址处,而int类型占4个字节空间,以4为倍数的地址就有0,4,8等。编译器会优先按照自然对齐进行数据地址分配

结构体所占内存的字节数——内存对齐相关推荐

  1. 结构体所占字节数的计算

    结构体所占字节数遵循以下原则: 1. 结构体的大小等于结构体内最大成员大小的整数倍 2. 结构体内的成员的首地址相对于结构体首地址的偏移量是其类型大小的整数倍,比如说double型成员相对于结构体的首 ...

  2. 关于C语言中的结构体所占的字节数 sizeof(struct)

    C语言中的结构体所占的字节数 ,用sizeof求一个结构体的大小 C语言中用sizeof求结构体所占字节数的详细方法. 一.非嵌套结构体 struct one{char a; // 1(char所占字 ...

  3. C++_类和结构体所占内存大小,静态成员问题

    C++_类和结构体所占内存大小,静态成员问题 静态成员未初始化或者未调用(当然静态成员必须类外初始化才能调用)是不占内存的.静态成员不占类或结构体的内存 静态成员函数同样只声明未定义同样不占内存 指针 ...

  4. 【VS开发】【编程开发】【C/C++开发】结构体中的数组与指针的内存分配情况说明...

    [VS开发][编程开发][C/C++开发]结构体中的数组与指针的内存分配情况说明 标签:[VS开发] [编程开发] 主要是疑惑在结构体定义的数组的内存空间与指针动态分配的内存空间,在地址上连续性.以及 ...

  5. C语言结构体及函数传递数组參数演示样例

    C语言结构体及函数传递数组參数演示样例 注:makeSphere()函数返回Sphere结构体,main函数中.调用makeSphere()函数,传递的第一个參数为数组,传递的数组作为指针. post ...

  6. C 结构体嵌套一级指针 二级指针 动态分配内存

    https://blog.csdn.net/xielinhua88/article/details/51364623 点击打开链接 #define _CRT_SECURE_NO_WARNINGS #i ...

  7. C#开发笔记之22-C#中的int、long、float、double等类型都占多少个字节的内存。

    本文由 比特飞 原创发布,欢迎大家踊跃转载. 转载请注明本文地址:C#开发笔记之22-C#中的int.long.float.double等类型都占多少个字节的内存. | .Net中文网. C#开发笔记 ...

  8. 结构体类型的定义及所占内存的字节数

    C 语言允许用户自定义数据类型,典型的代表就是结构体,结构体类型和数组一样,都属于构造数据类型.它们之间的不同点就在于,数组是将相同类型的数据单独放在一起来存储,而结构体允许逻辑上相关,但类型不同的数 ...

  9. 共用体和结构体所占内存大小的计算方法

    共同体作用:让几个不同类型的变量共享同一个内存地址. 共用体所占内存大小:共用体所占内存的大小即公用体中长度最大元素所占用的字节数. #include<stdio.h> typedef u ...

最新文章

  1. 数据结构——堆栈的C语言实现
  2. 【Python】shutil内置模块复制和重命名文件
  3. 81. Search in Rotated Sorted Array II
  4. php curl CURLOPT_TIMEOUT_MS 小于1秒 解决方案
  5. [TACL18]隐式句法树模型真的能学到句子中有意义的结构吗?
  6. 《JavaScript 高级程序设计》第三章:基本概念
  7. Win10中卸载IE11
  8. 计算机中心pdca,信息中心日常运维工作PDCA持续改进.docx
  9. 电机控制方法以及区别
  10. 气象大数据平台(天擎)数据读取方法(python)(地面资料下载)
  11. VScode的源代码管理简易使用
  12. Java等额本息实现
  13. Tivoli Netcool/OMNIbus
  14. python之使用cmd命令行写程序
  15. 我相信希望,我相信明天~~
  16. 2022第二届网刃杯网络安全大赛-Web
  17. 响应式编程(反应式编程)的来龙去脉(同步编程、多线程编程、异步编程再到响应式编程)
  18. 孩子想养宠物,该不该同意?
  19. 以太网帧与ieee 802.3帧
  20. R 报错:参数不是数值也不是逻辑值:回覆NA--数据科学新类型tibble

热门文章

  1. 各种https证书类型有什么不同
  2. 网页链接点击跳转微信添加微信或者打开小程序
  3. 进制转化及数据类型相关内容
  4. matlab激光加工,科协五分钟|用Matlab实现激光扫描测距绘制面型
  5. 轻松获取布局截图 或友盟分享截图
  6. Web3:打造一个公平、开发的价值互联网
  7. 中国防篡改袋行业现状调研及趋势分析报告
  8. 社工库html页面,建立社工库
  9. jQuery获取指定ul下的li
  10. 手机office使用 手机office不登录 手机office不联网 手机office查询功能