嵌入式C语言之struct内存分配分析

本文源于微信号《嵌入式ARM》。链接:http://mp.weixin.qq.com/s/j2mk6jY79nrJge2cDZVH_A


对结构MyStruct采用sizeof会出现什么结果呢?sizeof(MyStruct)为多少呢?

 

也许你会这样求:sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13

 但是当在VC中测试上面结构的大小时,你会发现sizeof(MyStruct)=16。你知道为什么在VC中会得出这样一个结果吗?

 其实,这是VC对变量存储的一个特殊处理。为了提高CPU的存储速度,VC对一些变量的起始地址做了对齐处理。

在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。

下面列出常用类型的对齐方式(vs6.0&vs8.0,32位系统)

 

 各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节VC会自动填充。同时VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。

 

下面用前面的例子来说明VC到底怎么样来存放结构的。

 

为上面的结构分配空间的时候,VC根据成员变量出现的顺序和对齐方式,依次分配。

 1)先为第一个成员dda1分配空间,其起始地址跟结构的起始地址相同,刚好偏移量0刚好为sizeof(double)的倍数,该成员变量占用zeof(double)=8个字节;

 2)接下来为第二个成员dda分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为8,是sizeof(char)的倍数,所以把dda存放在偏移量为8的地方满足对齐方式,该成员变量占用sizeof(char)=1个字节;

 3)接下来为第三个成员type分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为9,不是sizeof(int)=4的倍数,为了满足对齐方式对偏移量的约束问题,VC自动填充3个字节(这三个字节没有放什么东西),这时下一个可以分配的地址对于结构的起始地址的偏移量为12,刚好是=4的倍数,所以把type存放在偏移量为12的地方,该成员变量占用sizeof(int)=4个字节;

 4)这时整个结构的成员变量已经都分配了空间,总的占用的空间大小为:

8+1+3+4=16,刚好为结构的字节边界数(即结构中占用最大空间的类型所占用的字节数sizeof(double)=8)的倍数,所以没有空缺的字节需要填充。

 5)所以整个结构的大小为:

sizeof(MyStruct)=8+1+3+4=16,其中有3个字节是VC自动填充的,没有放任何有意义的东西。

 

下面再举个例子,交换一下上面的MyStruct的成员变量的位置,使它变成下面的情况:

 

 这个结构占用的空间为多大呢?在VC6.0环境下,可以得到sizeof(MyStruct)=24。结合上面提到的分配空间的一些原则,分析下VC怎么样为上面的结构分配空间的。

 所有成员变量都分配了空间,空间总的大小为1+7+8+4=20,不是结构的节边界数(即结构中占用最大空间的类型所占用的字节数sizeof(double)=8)的倍数,所以需要填充4个字节,以满足结构的大小为sizeof(double)=8的倍数。所以该结构总的大小为:sizeof(MyStruct)1+7+8+4+4=24。其中总的有7+4=11个字节是VC自动填充的,没有放任何有意义的东西。

 

VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式。VC中提供了#pragma pack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。

 下面举例说明其用法:

 

 

以上结构的大小为16,下面分析其存储情况,首先为m1分配空间,其偏移量为0,满足我们自己设定的对齐方式(4字节对齐),m1占用1个字节。接着开始为m4分配空间,这时其偏移量为1,需要补足3个字节,这样使偏移量满足为n=4的倍数(因为sizeof(double)大于n,m4占用8个字节。接着为m3分配空间,这时其偏移量为12,满足为4的倍数,m3占用4个字节。这时已经为所有成员变量分配了空间,共分配了16个字节,满足为n的倍数。如果把上面的#pragma pack(4)改为#pragma pack(16),那么我们可以得到结构的大小为24

 VC6中,Project SettingsàC/C++àStruct member alignment中默认值为8Bytes *Struct member alignment用以指定数据结构中的成员变量在内存中是按几字节对齐的,根据计算机数据总线的位数,不同的对齐方式存取数据的速度不一样。这个参数对数据包网络传输等应用尤为重要,不是存取速度问题,而是数据位的精确定义问题,一般在程序中使用#pragma pack来指定。





总结之,即:
(1)可以设置不同的对齐方式,设置方式如上面所述,一般系统默认为8字节对齐。而我所知,嵌入式系统中一般默认4字节对齐?(vs2015默认4字节对齐)
(2)VC中提供了#pragma pack(n)来设定变量以n字节对齐方式。即在结构体前后分别以#pragma pack(n),#pragma pack()进行对齐设置。
n字节对齐就是说变量存放的起始地址的偏移量有两种情况:
第一、如果n大于等于该变量类型所占用的字节数,那么偏移量必须是该类型的整数倍。
第二、如果n小于该变量的类型所所占用的字节数,那么偏移量必须是n的整数倍。

结构的总大小也有个约束条件,分下面两种情况:
如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。

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

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

相关文章

PostMessage发送字符串和结构体

2019独角兽企业重金招聘Python工程师标准>>> 1.首先定义消息变量 #define WM_POST_MSG WM_USER 2 2.增加消息处理函数 afx_msg LRESULT UpdateStatic(WPARAM wParam, LPARAM lParam); 3.增加消息映射 ON_MESSAGE(WM_POST_MSG,UpdateStatic) 当调用PostMessage函…

SPI、I2C、UART(即串口)三种串行总线详解

以下内容均来源于网络资源的学习与整理,如有侵权请告知删除。 参考博客 几个串口协议学习整理 UART IIC SPI_mainn的博客-CSDN博客 SPI、I2C、UART三种串行总线的原理、区别及应用_嵌入式Linux,的博客-CSDN博客 RS-232 和 UART 之间有什么区别? - 知乎…

用数据辅助设计-搜索中的实践

设计时不能单凭经验和直觉,因为涉及到的目标人群、场景、操作习惯的不同。为了获取更准确、有效的信息去辅助、检测设计,设计师会选择定性(用户访谈、焦点小组)和定量(调研问卷、网站数据分析)的方式进行用…

在IBM服务器安装Windows server 2012的心得

一个简单的问题被我搞复杂了! 前些日子,由于连接服务器时卡顿、没有反应,我把服务器强制重启了,之后很不幸地,系统开机进入界面后,不断地转圈圈,一段时间后提示“你的电脑遇到问题,…

VisualVM远程连接Linux服务器通过jstatd方式监控JVM内存状态

2019独角兽企业重金招聘Python工程师标准>>> VisualVM远程连接Linux监控JVM的方式有两种,一种是jstatd,另外一种是JMX,这里描述jstatd的方式: 1.通过google/baidu出来的文章做法大致都雷同这里给出我开始参考的连接http://lixjluck.iteye.com/blog/516447 2. 但是…

SD读写流程

一、1bit-4bit数据传输对比 CPU/EDMA与SD的数据传输可以设置为1bit或4bit模式,1bit模式仅使用DAT0数据线,4bit模式使用DAT3-DAT0四位数据线。例如,传输512字节的数据,传输的数据格式如下图所示: 二、读写命令 读写分为…

ubuntu14.04 64bit主机下面安装android的NDK开发环境

通过wget工具下载bin包: $ wget -c http://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin1 2,因为下载下来的是bin包,所以可以直接移动到需要安装的目录下面。 将Android NDK bin包移动到你想要的目录下,如 /opt/NDK/1 $ …

二维数组数和指针操作的理解

#include<string.h> #include <stdio.h> int main(void) {int a[4][2] { { 2,4 },{ 6,8 },{ 1,3 },{ 5,7 } };char *p[5] { "acvsadf", "cwerqwenn", "tttttt" };//字符串指针数组int c[4] { 0,1,2,3 };int *ptr c;/*这个正确&…

最近重构公司消息服务的架构设计

目标 研发一套独立的消息系统&#xff0c;此系统进行集中配置管理供各业务系统使用&#xff0c;用于支撑站内信、短信通知、短信验证码、邮件、微信消息、APP消息、IM等消息形式。 架构 1&#xff09; 基于消息队列采用发布、订阅模式。消息的生产者为对外的消息接口&#xff0…

高性能的MySQL(6)查询慢与重构查询

只有好的库表结构、合理的索引还不够&#xff0c;我们还需要合理的设计查询&#xff0c;齐头并进&#xff0c;一个不少才能充分发挥MySQL的优势。一、查询为什么会慢&#xff1f;每一个查询由一系列的子任务组成&#xff0c;每个子任务都会消耗一定的时间。这个我们在之前的单个…

一道大小端题目

今天看到一道关于大小端的题目&#xff0c;觉得很有趣&#xff0c;理解一番后摘抄如下&#xff1a; 题目&#xff1a; 示意图&#xff1a; 结果说明&#xff1a; 小端模式 大端模式

算法复杂度速查表

图例 数据结构操作 数组排序算法 图操作 堆操作 大 O 复杂度图表 Big O 复杂度 推荐阅读 Cracking the Coding Interview: 150 Programming Questions and Solutions[33] Introduction to Algorithms, 3rd Edition[34] Data Structures and Algorithms in Java (2nd Edition)…

遇到异常:这可能是由某个扩展导致的

重构机房收费系统&#xff0c;我用EA画完UML图&#xff0c;打算用EA自己生成VB.NET代码&#xff0c;这样会方面些。没想到事情没有我想象的那么简单&#xff0c;可能是第一次尝试的原因&#xff0c;导入代码的过程中问题是一个接着一个。不过还好&#xff0c;虽然沿途困难重重&…

文件IO——文件IO相关概念

1、API &#xff08;1&#xff09;基于linux做应用开发&#xff0c;其实就是通过调用linux系统提供的API来实现。 &#xff08;2&#xff09;API 是一些由linux系统提供的函数&#xff0c;给应用层使用&#xff0c;以完成一定的功能。 &#xff08;3&#xff09;常用的文件IO的…

git使用小记

1. 基本操作 全局配置&#xff1a; git config --global user.name xx git config --global user.email xxx 初始化一个仓库&#xff1a; git init 添加&#xff1a; git add "file1.txt" git commit -m "添加文件1" 比较&#xff1a;分别列出每个文件…

LINUX内核之普通自旋锁

LINUX内核之普通自旋锁 CopyLeft by ICANTH&#xff0c;I Can do ANy THing that I CAN THink&#xff01;~ Author&#xff1a;WenHui&#xff0c;WuHan University&#xff0c;2012-6-15 PDF版阅读地址&#xff1a;http://www.docin.com/p1-424285718.html 普通自旋锁 自旋锁…

MFC COMBO-BOX最详细教程

找了好多&#xff0c;这是讲的最清楚的&#xff0c;与大家共享&#xff01; 转&#xff1a;https://blog.csdn.net/fym0121/article/details/7515862 当你只需从一列对象中选出一个时&#xff0c;使用COMBO BOX是一个好主意&#xff0c;因为它节省空间。这篇文章讲述了如何使…

uboot源码——主Makefile的分析

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 参考博客&#xff1a;u-boot Makefile完全解读_williamwang2013的博客-CSDN博客 参考博客&#xff1a;U-boot主Makefile分析_XiaoBaWu的博客-CSDN博客 参考博客&#xff1a;U-boot配置及编译阶段…

Designing Virtual Connect for vSphere 5.x

Designing Virtual Connect for vSphere 5.x如何在 HP C7000刀笼使用VC以满足vSphere 5.x 英文视频连接如下&#xff1a;http://professionalvmware.com/2013/05/vbrownbag-follow-up-designing-virtual-connect-for-vsphere-with-joe-clark-elgwhoppo/1&#xff1a;首先介绍一…

VMware vCenter Converter 关闭SSL加密,提高35-40%性能

VMware vCenter Converter 关闭SSL加密,提高35-40%性能原文&#xff1a;http://www.vmwarearena.com/2013/07/improving-transfer-rate-of-p2v-and-v2v.htmlVMware vCenter Converter Standalone 5.0 is a free tool from VMware to easily perform P2V(Physical to virtual co…