繁体   English   中英

sizeof如何计算结构的尺寸

[英]How does sizeof calculate the size of structures

我知道,由于对齐,在32位体系结构上,一个char和一个int被计算为8个字节,但是最近我遇到了一种情况,其中sizeof运算符将3个短裤的结构报告为6个字节。 代码如下:

#include <iostream>
using namespace std ;

struct IntAndChar
{
    int a ;
    unsigned char b ;
};


struct ThreeShorts
{
    unsigned short a ;
    unsigned short b ;
    unsigned short c ;
};


int main()
{
    cout<<sizeof(IntAndChar)<<endl; // outputs '8'
    cout<<sizeof(ThreeShorts)<<endl; // outputs '6', I expected this to be '8'
    return 0 ;
}

编译器:g ++(Debian 4.3.2-1.1)4.3.2。 这真的使我感到困惑,为什么不对包含3个短裤的结构强制执行对齐?

那是因为int是4个字节,并且必须与4个字节的边界对齐。 这意味着包含int ANY struct也必须至少对齐4个字节。

另一方面, short是2个字节,只需要对齐2个字节的边界即可。 如果包含shortstruct不包含任何需要较大对齐的内容,则该struct还将对齐2个字节。

这真的使我感到困惑,为什么不对t强制执行对齐

您希望它具有什么对齐方式?

短裤可以在2个字节的边界上对齐,而不会造成不良影响(假设此处使用通用的x86编译器。)。 因此,如果您创建一个struct ThreeeShorts数组,那么大小为6的结构就可以了,因为该数组中的任何元素都将从2字节边界开始。

您的struct IntAndChar包含一个int,int需要4个字节的对齐方式,因此,如果您创建一个struct IntAndChar的数组, struct IntAndChar其大小必须为8,以便下一个元素在4个字节的边界上对齐。

如果我们不考虑数组,那么struct IntAndChar为5个字节就没关系,当您在堆栈中创建一个堆栈或将其用作复合成员时,编译器只会从4字节边界开始分配它另一个结构。

您总是可以通过执行sizeof(arrayofT)/ sizeof(T)来获取数组中元素的数量,并且保证数组元素可以相邻存储,从而可以通过步进N * sizeof(arrayelementtype)来获取第n个元素。 )从头开始算起字节,这就是您会在末尾看到struct的主要原因。

我不知道您将charint计算为“ 8字节”的想法。 不,每种类型都是根据其大小计算的:在32位平台上, char为1, int为4(不是8,而是4)。 每种类型的对齐要求通常与其大小相同(尽管不必如此)。

因此,当结构包含相同类型的成员时,该结构的总大小通常将是其成员大小的确切总和:3个char的结构将具有3的大小,而2个结构将具有2个char的结构int的大小为8。

显然,您平台上的short类型的大小为2,因此,预计3个short的结构的大小为6,这正是您所观察到的。

但是,当您的结构包含不同类型的成员时,则不同类型的对齐要求之间的差异将发挥作用。 如果下一个字段的对齐要求比上一个字段的对齐要求严格,则编译器可能必须在这些字段之间添加一些填充字节(以正确对齐下一个成员),这将影响结构的最终大小。 同样,编译器可能必须在结构的最后一个成员之后添加一些额外的填充字节,才能满足数组中的对齐要求。

例如,如下所示的结构

struct S {
  char c;
  int i;
};

将最有可能在您的平台上占用8个字节,因为在char成员之后需要3个填充字节。 注意, char计为1, int为4,而它们之间的额外3个填充字节使之为8。

还要注意,这可能很容易引入结构的最终大小对成员声明顺序的依赖性。 例如,这种结构

struct S1 {
  char c1;
  int i;
  char c2;
};

您平台上的尺寸可能为12,而这一尺寸

struct S2 {
  int i;
  char c1;
  char c2;
};

将仅占用8个字节。 最后一个示例旨在说明该结构的最终大小无法用每个成员“计数”多少字节来表示。 成员之间的关系也很重要。

它完全取决于实现,但是如果您的系统可以访问结构中三个short的任何一个而不必担心对齐,那么它可以访问ThreeShorts数组中的任何short ,因此可以访问任何数据成员,而不必担心对齐。 因此,无需更严格地对齐结构。

对于IntAndChar例如, int大概有大小4和实施涉及其对齐。 为了确保IntAndChar数组中的每个int成员正确对齐,必须填充该结构。

所述sizeof阵列T[n]被精确地定义为sizeof(T) * n

该链接应该有帮助: http : //en.wikipedia.org/wiki/Data_structure_alignment

ThreeShorts所有成员都是两个字节对齐的。

是的,我有同样的问题。 我有以下结构

struct Node{
    short digit;
    Node* next;
};
    cout<<":"<<sizeof(Node)<<":"<<sizeof(short)<<":"<<sizeof(Node*)<<endl;

这给了我:: 8:2:4 ?? 为什么该结构的总和= 8,但是各个元素不求和? 这是因为内存对齐,因此在内存中填充了额外的2个字节用于对齐。 谢谢

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM