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

数据对齐:

许多计算机系统对基本数据类型合法地址做出了一些限制,要求某种类型对象的地址必须是
某个值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,一经查实,立即删除!

相关文章

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;会弹出 启动或…

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…

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…

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…

深度学习中的一些常见的激活函数集合(含公式与导数的推导)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密钥。支持加密密钥…

Shell Notes(1)

> vi复制粘贴 光标移动到要复制的部分的开头&#xff0c;Esc退出插入模式&#xff0c;按v进入Visual模式&#xff0c;用hjkl选中要复制的部分 按Y或者yy&#xff0c;复制 移动光标到目标位置&#xff0c;按p&#xff0c;粘贴 > echo –e 参数 –e 可以使echo解释由反斜杠…

mysql多表查询语句_mysql查询语句 和 多表关联查询 以及 子查询

1.查询一张表&#xff1a;select * from 表名&#xff1b;2.查询指定字段&#xff1a;select 字段1&#xff0c;字段2&#xff0c;字段3….from 表名&#xff1b;3.where条件查询&#xff1a;select字段1&#xff0c;字段2&#xff0c;字段3 frome表名 where 条件表达式&#x…

Pytorch 自定义激活函数前向与反向传播 sigmoid

文章目录Sigmoid公式求导过程优点&#xff1a;缺点&#xff1a;自定义Sigmoid与Torch定义的比较可视化import matplotlib import matplotlib.pyplot as plt import numpy as np import torch import torch.nn as nn import torch.nn.functional as F%matplotlib inlineplt.rcPa…

js高级编程_这位设计师用Processing把创意编程玩到了极致!

Processing作为新媒体从业者的必备工具&#xff0c;近来却越来越成为设计师们的新宠&#xff01;今天小编将介绍以为用Processing把创意编程玩到极致的设计师Tim Rodenbrker。“我们的世界正在以惊人的速度变化。新技术为创作带来了根本性的转变。编程是我们这个时代最宝贵的技…

微软.NET Framework 4.5.2 RTM正式版

今天&#xff0c;微软.NET开发团队发布.NET Framework 4.5.2 RTM正式版。新版框架继续高度兼容现有的.NET Framework 4、4.5、4.5.1等版本&#xff0c;该版本框架与旧版的.NET Framework 3.5 SP1和早期版本采取不同的处理方式&#xff0c;但与.NET Framework 4、4.5相比&#x…

Pytorch 自定义激活函数前向与反向传播 Tanh

看完这篇&#xff0c;你基本上可以自定义前向与反向传播&#xff0c;可以自己定义自己的算子 文章目录Tanh公式求导过程优点&#xff1a;缺点&#xff1a;自定义Tanh与Torch定义的比较可视化import matplotlib import matplotlib.pyplot as plt import numpy as np import torc…