c语言结构体没赋值会占内存吗(C了解结构体的内存对齐)
我们使用的电子计算机绝大部分都是冯·诺依曼结构的机器,遵循“存储程序”的概念。数据处理以存储为前提,在编程中数据如何“存得进去,取得出来”,并且符合空间、时间效率的要求,在考虑数据结构和算法时,都要有清晰的内存映像的图景。
你可以想像在定义一个结构体时,就是在构建一块内存空间的架构。当定义结构体变量时,就会实际分配内存空间,这块内存空间的首地址就是结构体变量的名称,各成员变量名对应各小块空间的首地址。访问各成员变量使用的点号,就如同是大块空间的地址到成员空间的映射或偏移。
如以下定义的结构体:
#include<iostream> struct Readout { char hour; int value; char seq; }testSize; void main() { std::cout<<sizeof(testSize); //12 }
你可能会想到以下的内存映像图景(以下都是假设32位,int类型占用4个字节长度的机器):
可能会认为以下代码的输出应该是6(各成员大小的和)。
std::cout<<sizeof(testSize);
但实际的输出却是12。这就是结构体的内存对齐,编译器会自动对齐结构体数据成员以提高运行效率。
结构体的字节对齐是指编译器在为结构体变量分配内存时,保证下一个成员的偏移量为成员类型的整数倍。因此,对于一些结构体变量来说,其大小并不等于结构体中每一个成员大小的总和。编译器基于效率因素增加一些额外字节以使存储边界对齐。
这样会在内存中留下一些“空洞”而增加了内存空间的占用:
这也就解释了内存空间占用是12而不是6的原因。
您可以通过简单地按大小(首先是最大的成员)对成员排序来最小化浪费的空间。
struct Readout { int value; char hour; char seq; }testSize; void main() { std::cout<<sizeof(testSize);//8 }
此时的内存占用是8个字节:
也就是说,因为对齐的原因,还是留下了一些内存“空洞”。
如果是以下结构定义,size也是8: struct Readout { char hour; char seq; int value; }testSize;
通过以下语句可以强制地声明结构体内存对齐的长度,如:
#pragma pack(1) //C编译器按n字节对齐。
如果有声明以上语句,则下面语句的输出就是6了:
std::cout<<sizeof(testSize);//6
基本的规则是:
结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要,编译器会在成员之间加上填充字节;
结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在在最末一个成员之后加上填充字节。
-End-
,免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com