【转】彻底搞清计算结构体大小和数据对齐原则

数据对齐:

许多计算机系统对基本数据类型合法地址做出了一些限制,要求某种类型对象的地址必须是
某个值K(通常是2,4或8)的倍数。这种对齐限制简化了形成处理器和存储器系统之间的接口的硬件
设计。例如,假设一个处理器总是从存储器中取出8个字节,则地址必须为8的倍数。如果我们能保
证将所有的double类型数据的地址对齐成8的倍数,那么就可以用一个存储器操作来读或者写值了。
否则,我们可能需要执行两次存储器访问,因为对象可能被分放在两个8字节存储块中。
当数据类型为结构体时,编译器可能需要在结构体字段的分配中插入间隙,以保证每个结构元素都
         满足它的对齐要求。而结构本身对它的地址也有一些对齐要求,此时可能需要在结构末尾填充一些
         空间,以满足结构体整体的对齐----向结构体元素中最大的元素对齐。稍后会用代码说明!!!
       
         Linux和Microsoft Windows的对齐方式有何不同:
               一.Linux的对齐策略:
在Linux中2字节数据类型(例如short)的地址必须是2的倍数,而较大的数据类型(例如int,int *
,float和double)的地址必须是4的倍数。也就是说Linux下要么2字节对齐,要么4字节对齐,没
有其他格式的对齐。
              二.Microsoft Windows的对齐策略:
在Windows中对齐要求更严--任何K字节基本对象的地址都必须是K的倍数,K=2,4,或者8.
特别地,double或者long long类型数据的地址应该是8的倍数。可以看出Windows的对齐策略和
Linux还是不同的。稍后用代码说明!!!
 接下来用代码和图文说明两者的对齐方式(不同的对齐方式产生的结构体大小不同):
测试代码如下:
    /  //   filename:DataAlignment  /  #include<stdio.h>  typedef struct   {  char c;  int i[2];  double v;  }S;  int main()  {  printf("size of S = %d\n", sizeof(S));  return 0;  }  

 

程序中定义了一个结构体,在没有任何数据对齐时内存布局如下:
一.在红帽Linux i686上编译编译后结构S的布局如下:
                
由于要保证结构体每个元素都要数据对齐,因此必须在c和i[0]之间插入3字节的间隙(图中阴影部分为编译器插入的间隙)
使得i[0]和后面的元素的的偏移量都为4的倍数,这样最终S结构大小为20字节。
运行程序结果为:
 size of S = 20
           
二.在Microsoft Windows 上编译后S的内存布局如下:
在windows下int类型4个字节,因此int类型要向4字节对齐,double类型8字节,因此要向8字节对齐。因此在
c和i[0]之间插入3字节的间隙(图中阴影部分),使得i[0]的偏移量为4的倍数,同时在i[1]和v之间插入4字节的间隙,
使得v的偏移量为8的倍数。这样最终S结构的大小为24字节。
运行程序结果为:
 size of S = 24
          从以上对比可以看出Linux下和windows下的对齐策略是不同的,这就导致在两个平台下结构体的大小不同。
           
         现在考虑如下代码:
              
    #include<stdio.h>  typedef struct  {  int i;  int j;  char c;  }S1;  int main()  {  printf("size of S1 = %d\n", sizeof(S1));  return 0;  }  

 

可能很多人认为编译后运行结果为9,以为结构体的每个元素都满足各自的对齐要求。其实不然,别忘了还有要考虑
结构体整体的对齐。假如有如下声明:
S1  d[4];
如果这样分配9个字节,不可能满足d的每个元素的对齐要求,因为这些元素的地址分别为xd,xd+9,xd+18,
xd+27。这样只有第一个元素满足4字节对齐的要求,而其他的元素的地址都不是4的倍数。

因此编译器会在结构体的末尾填充3字节满足结构体整体的对齐要求,填充后的内存布局如下:
这样一来,d的元素的地址分别为xd,xd+12,xd+24,xd+36,满足4字节的整数倍,这样最终S1的大小
为12字节,而不是9字节.

总结:通过代码的对比,可以看出Linx和Windwos的数据对齐有所差异,这就导致
在一些情况下两者平台结构体类型大小的不同。通过以上示例分析我们可以很简单的
计算出在任何平台下结构体的大小。读者可以找相关的练习题继续练习下,验证结果
的正确性。相信仔细阅读本文应该能搞定所有类似的问题!!!
原文地址:http://blog.csdn.net/qianghaohao/article/details/51011418

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/260507.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python里pip是什么意思_python使用pip的方法是什么

python使用pip的方法是什么 发布时间&#xff1a;2020-08-25 11:51:08 来源&#xff1a;亿速云 阅读&#xff1a;104 作者&#xff1a;小新 小编给大家分享一下python使用pip的方法是什么&#xff0c;相信大部分人都还不怎么了解&#xff0c;因此分享这篇文章给大家参考一下&am…

Pytorch 学习率衰减 之 余弦退火与余弦warmup 自定义学习率衰减scheduler

学习率衰减&#xff0c;通常我们英文也叫做scheduler。本文学习率衰减自定义&#xff0c;通过2种方法实现自定义&#xff0c;一是利用lambda&#xff0c;另外一个是继承pytorch的lr_scheduler import math import matplotlib.pyplot as plt import numpy as np import torch i…

c++ 字符串赋给另一个_7.2 C++字符串处理函数

点击上方“C语言入门到精通”&#xff0c;选择置顶第一时间关注程序猿身边的故事作者闫小林白天搬砖&#xff0c;晚上做梦。我有故事&#xff0c;你有酒么&#xff1f;C字符串处理函数C语言和C提供了一些字符串函数&#xff0c;使得用户能很方便地对字符串进行处理。这些是放在…

如何检测远程主机上的某个端口是否开启

有时候我们要测试远程主机上的某个端口是否开启&#xff0c;无需使用太复杂的工作&#xff0c;windows下就自带了工具&#xff0c;那就是telnet。怎么检测呢&#xff0c;按下面的步骤&#xff1a; 1、安装telnet。我的win7下就没有telnet&#xff0c;在cmd下输入telnet提示没有…

Windows10 + WSL (Ubuntu) + Anaconda + vscode 手把手配置python运行环境(含虚拟环境)

配置WSL windows桌面下&#xff0c;按下面顺序可以找到 "启动或关闭windows功能” &#xff0c; 开始 -> 设置 -> 应用 -> 应用和功能 -> 可选功能 -> 相关设置下 更多Windows功能&#xff08;滚动鼠标到底部&#xff09;点击后&#xff0c;会弹出 启动或…

Inline函数使用注意事项

Inline函数使用注意事项 1.在一个文件中定义的inline函数不能再另一个文件中使用 2.inline函数应简洁&#xff0c;只有少数几个语句。 3.在inline函数中不能有循环&#xff0c;if&#xff0c;switch语句。 4.inline函数要在调用和声明前定义&#xff01;&#xff01;&#xff0…

2019编译ffepeg vs_如何在windows10下使用vs2017编译最新版本的FFmpeg和ffplay

该文章描述了如何在windows10 64位系统下面编译出FFmpeg的库及其自带的ffplay播放器&#xff0c;而且全部采用最新的版本&#xff0c;这样我们可以在vs2017的ide下调试ffplay&#xff0c;能使我们更容易学习FFmpeg的架构以及音视频播放器的原理。步骤&#xff1a;1.安装vs2017在…

训练集山准确率高测试集上准确率很低_推荐算法改版前的AB测试

编辑导语&#xff1a;所谓推荐算法就是利用用户的一些行为&#xff0c;通过一些数学算法&#xff0c;推测出用户可能喜欢的东西&#xff1b;如今很多软件都有这样的操作&#xff0c;对于此系统的设计也会进行测试&#xff1b;本文作者分享了关于推荐算法改版前的AB测试&#xf…

C#实现渐变颜色的Windows窗体控件

C#实现渐变颜色的Windows窗体控件! 1,定义一个BaseFormGradient,继承于System.Windows.Forms.Form2,定义三个变量: privateColor _Color1 Color.Gainsboro; privateColor _Color2 Color.White; privatefloat_ColorAngle 0f;3,重载OnPaintBackground方法 protecte…

ios7开发学习笔记-包括c oc 和ios介绍

请查看我的新浪资料分享 http://iask.sina.com.cn/u/2430843520 转载于:https://www.cnblogs.com/langtianya/p/3708298.html

Windows下 jupyter notebook 运行multiprocessing 报错的问题与解决方法

文章目录测试用的代码错误解决方法测试用的代码 下面每一个对应一个jupyter notebook的单元格 import time from multiprocessing import Process, Queuedef generator():c 0while True:time.sleep(1.0) # read somethingyield cc 1%%timeds generator() for i in range(3…

如何将javaweb项目部署到linux下

以下是对将javaweb项目部署到linux下的方法进行了详细的分析介绍一般都在windows下开发的现在部署到linux下将项目达成war包(用eclipse项目右键>Export>选择war file)将tomcat(用winSCP当然你也可以用secureCRT用securCRT需要建立sftp(即上传文件的目录)用put tomcat命令…

vc mysql_vc6.0连接mysql数据库

一、MySQL的安装Mysql的安装去官网下载就可以。。。最新的是5.7版本。。二、VC6.0的设置(1)打开VC6.中选0 工具栏Tools菜单下的Options选项&#xff0c;在Directories的标签页中右边的“Show directories for:”下拉列表中“Includefiles”&#xff0c;然后在中间列表框中添加你…

python class用法_python原类、类的创建过程与方法

【小宅按】今天为大家介绍一下python中与class 相关的知识……获取对象的类名python是一门面向对象的语言&#xff0c;对于一切接对象的python来说&#xff0c;咱们有必要深入的学习与了解一些知识首先大家都知道&#xff0c;要获取一个对象所对应的类&#xff0c;需要使用clas…

网易公开课

计算机科学及编程导论 http://v.163.com/special/opencourse/bianchengdaolun.html 抽象编程 http://v.163.com/special/opencourse/abstractions.html转载于:https://www.cnblogs.com/anyboo/archive/2012/08/24/2653537.html

深度学习中的一些常见的激活函数集合(含公式与导数的推导)sigmoid, relu, leaky relu, elu, numpy实现

文章目录Sigmoid(x)双曲正切线性整流函数 rectified linear unit &#xff08;ReLu&#xff09;PReLU(Parametric Rectified Linear Unit) Leaky ReLu指数线性单元 Exponential Linear Units &#xff08;ELU&#xff09;感知机激活%matplotlib inline %config InlineBackend.f…

最牛X的GCC 内联汇编

正如大家知道的&#xff0c;在C语言中插入汇编语言&#xff0c;其是Linux中使用的基本汇编程序语法。本文将讲解 GCC 提供的内联汇编特性的用途和用法。对于阅读这篇文章&#xff0c;这里只有两个前提要求&#xff0c;很明显&#xff0c;就是 x86 汇编语言和 C 语言的基本认识。…

mysql的告警日志_MySQL Aborted connection告警日志的分析

前言&#xff1a;有时候&#xff0c;连接MySQL的会话经常会异常退出&#xff0c;错误日志里会看到"Got an error reading communication packets"类型的告警。本篇文章我们一起来讨论下该错误可能的原因以及如何来规避。1.状态变量Aborted_clients和Aborted_connects…

hosts多个ip对应一个主机名_一个简单的Web应用程序,用作连接到ssh服务器的ssh客户端...

WebSSH一个简单的Web应用程序&#xff0c;用作连接到ssh服务器的ssh客户端。它是用Python编写的&#xff0c;基于tornado&#xff0c;paramiko和xterm.js。特征支持SSH密码验证&#xff0c;包括空密码。支持SSH公钥认证&#xff0c;包括DSA RSA ECDSA Ed25519密钥。支持加密密钥…

Yii框架中使用PHPExcel导出Excel文件

Yii框架中使用PHPExcel导出Excel文件http://www.cnblogs.com/wgx214/p/3709521.html转载于:https://www.cnblogs.com/flying-tx/p/3714530.html