C语言中结构字节的计算方法

电脑杂谈  发布时间:2020-05-09 11:30:58  来源:网络整理

大小结构种群模型_计算结构体大小_尾大小公式怎样计算

在讨论计算方法之前,我们先讨论一些概念,一个是偏移量,另一个是内存对齐. 让我来谈谈偏移量,百度百科将其定义为: 存储单元的实际地址与其所在的段的段地址之间的距离称为段内偏移量,也称为“有效地址”或抵消. ”在结构中,它可能是指结构变量中成员地址与结构变量地址之间的差异. 然后谈谈内存对齐的概念: 当在内存中存储基本类型的数据时,计算机系统将对其位置有所限制. 系统将要求这些数据的第一个地址的值是某个数字的倍数,该数字称为数据类型的对齐模数. 尽管ANSI C标准没有强制要求相邻声明的变量在内存中应该相邻,但是编译器会自动帮助您解决此问题,即,相邻变量之间可能会填充一些字节. 因此,在此问题上,编译器有所不同.

因此,我们首先来讨论结构变量在Microsoft编译器中的对齐方式

1. 如果结构成员的第一个地址是其最宽的基本类型成员的整数倍. 当编译器为结构分配内存时,它首先找到最宽的基本成员,然后在内存中查找地址,并使用此最宽的基本数据类型的大小作为对齐模量

2. 结构中每个成员相对于第一个地址的偏移量是成员大小的整数倍. 如果不满足此要求,则编译器将自动添加字节. 当为结构成员打开内存时计算结构体大小,编译器将首先检查已开发内存的第一地址与结构变量的第一地址之间的偏移量. 如果它是成员体的整数倍,则存储此变量,否则将在该成员和上一个成员之间填充字节以实现整数倍

3. 如果结构占用的总内存大小是最大成员主体大小的整数倍,如果不是,则编译器将在末尾添加字节. 结构的最后一个成员不仅必须满足前两个原则,而且还必须满足最后一个条件.

让我们看几个例子.

尾大小公式怎样计算_计算结构体大小_大小结构种群模型

struct std

{

字符a;

int i;

float b;

};

尾大小公式怎样计算_计算结构体大小_大小结构种群模型

在VS 2017下,此结构的计算结果的大小为12. 然后将根据上述规则进行计算.

第一个是char a. 字符大小为1,与第一个地址的偏移量为0,然后为整数i. int i的大小为4,与第一个地址的偏移量为1,但1不是4的整数倍,因此编译器将自动填充char a和int i之间的字节. 所以i的偏移量是4. float 4的大小偏移量是int i的偏移量加上int i的大小,因此float b的偏移量大小是8,而8是4的倍数,所以会有没有字节填充. 结构的大小自然是最后8 + 4 = 12

由此也可以看出,结构的大小等于最后一个成员的大小加上其偏移量.

所以让我们来看另一个例子

struct std

{

尾大小公式怎样计算_计算结构体大小_大小结构种群模型

int i;

int c;

双b;

字符a;

};

然后我们使用先前的算法进行计算,int i的大小为4,偏移量为0,int c的大小为4,偏移量为4,双精度b的大小为8,偏移量Is 8. char a的大小为1,偏移量为16. 那么此结构的变量的大小为16 +1 = 17吗?答案肯定不是. 在VS的sizeof计算下,结果是24计算结构体大小,为什么是24,则将使用前面提到的最后一个原理. 结构的大小确实等于最后一个成员的偏移加上最后一个成员的大小,但是如果结构不满足结构中最大成员大小的整数倍的条件,则编译器将自动填写最后一个单词符合要求,即尽管我们计算的结果是17、17并非8的倍数,所以编译器会自动填充末尾的字节以使其成为8的倍数,即,自动扩展为24. ,

尾大小公式怎样计算_大小结构种群模型_计算结构体大小

然后让我们讨论一下GCC编译器下的模式. 在Windows环境中,将减少使用GCC编译器. 如果GCC编译器主要在Linux平台上使用,则它不遵循Microsoft编译器的某些准则,例如前面提到的对齐模数. Microsoft编译器下的对齐模数是结构成员中最大的大小,GCC编译器下的最大对齐模数只能是4. 这意味着对齐模数只能是1,2,4之一. 因此,我之前讨论的Microsoft编译器下的某些原理将稍有不同. 如果前面提到的成员的第一个地址的偏移量是成员大小的整数倍,则此处的偏移量会有所不同. 在GCC中,如果成员大小小于等于4的成员,则继续遵循先前的标准,但是如果成员大小大于4,则该结构的每个成员相对于该结构的第一个地址的偏移量只能是4的整数倍. 确定是否添加填充. 让我们看一个简单的例子.

struct std

{

字符b;

双c;

};

在此示例中,如果它基于Microsoft编译器,则计算的结构应为16,但在GCC编译器下为12. 原因如上所述.

尽管从理论上讲这是正确的,但是当我尝试时,我发现上述操作的结果是16,是的,它是16而不是12!为什么?这种理论是错误的,当然不是. 我们可以尝试在GCC下计算sizeof(int *)(它是int *而不是int). 您会发现结果为8(如果为sizeof(int),则结果为4),输出为8,这解决了我们的疑问. 64位系统的长度默认为8,32位系统的默认值为4. 这可以合理地解释为什么计算结果是16而不是12.

对齐模数的选择只能基于基本数据类型,因此结构嵌套结构就不会出现这种情况,因为稍后会添加其计算方法


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-204089-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 江万里
        江万里

        那么现在让你们在大陆投资只是为了把更多的台湾经济扣押在大陆

      热点图片
      拼命载入中...