首页 > 试题广场 >

求sizeof(A),sizeof(B)分别是多少。

[单选题]
class A{
    int a;
    short b;
    int c;
    char d;
};
class B{
    short b;
    int c;
    char d;
};
在64位机器上用gcc编译以上代码,求sizeof(A),sizeof(B)分别是多少。
  • 12 16
  • 12 12
  • 16 24
  • 16 12
gcc下编译答案是D
linux下double的对齐方式是4字节,而windows默认是8字节。。。
linux可以通过如下方式控制对齐方式
class B
{
        double a;
        short b;
        int c;
        char d;
}__attribute__((aligned(8)));
而WINDOWS是通过#pragma pack(n) 来控制编译器按照n个字节对齐
发表于 2015-03-09 21:28:30 回复(1)
 例如B,short本来占2个字节,但是下一个是int所以占4个字节,int占4个字节,char原本占1个字节,为了保证对齐数是4的倍数,所以最后的那个char也占了4个字节。这个是gcc编译器的规则。综上所述:4+4+4=12  所以要选择D选项。
编辑于 2021-02-19 18:10:30 回复(11)
其实不同编译器答案是不一样的。
gcc下编译答案是D
linux下double的对齐方式是4字节,而windows默认是8字节。。。
linux可以通过如下方式控制对齐方式。
而WINDOWS是通过 #pragma pack(n) 来控制编译器按照n个字节对齐。
但是如果按照大家比较能够理解的说法:
根据以下条件进行计算:
1、  结构体的大小等于结构体内最大成员大小的整数倍
2、  结构体内的成员的首地址相对于结构体首地址的偏移量是其类型大小的整数倍,比如说double型成员相对于结构体的首地址的地址偏移量应该是8的倍数。
3、  为了满足规则1和2编译器会在结构体成员之后进行字节填充!

那么答案就是:C


发表于 2015-03-16 22:32:51 回复(5)
这里有个很容易理解的帖子,终于搞懂了

一、为什么结构体计算这么乱?

答案是字节对齐,计算机存储系统中以Byte为单位存储数据,不同数据类型所占的空间不同,如:整型(int)数据占4个字节,字符型(char)数据占一个字 节,

短整型(short)数据占两个字节,等等。计算机为了快速的读写数据,默认情况下将数据存放在某个地址的起始位置,如:整型数据(int)默认存储 在地址能被

4整除的起始位置,字符型数据(char)可以存放在任何地址位置(被1整除),短整型(short)数据存储在地址能被2整除的起始位置。这样字节对齐有助于加快

计算机的取数速度,否则就得多花指令周期了。

二、字节对齐的细节和具体编译器实现相关,但一般而言,满足三个准则:

1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

2. 结构体每个成员相对于结构体首地址的偏移量都是当前成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;

3. 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。

说明:1、基本类型是指前面提到的像char、short、int、float、double这样的内置数据类型;

        2、对于复合数据类型,如结构体嵌套结构体,那么基本类型是指前面提到的像char、short、int、float、double这样的内置数据类型;

        3、我认为计算结构体大小的时候,主要用到准则2和准则3,对于准则1是编译器自动完成的,不需要过多理会。

        4、C++中类的可以看做是特殊的结构体,所以类的sizeof的计算和结构体是一样的。

三、下面拿具体的程序来详细说明:

 1 // sizeof(结构体).cpp : 定义控制台应用程序的入口点。  2 //  3  4 #include "stdafx.h"  5 #include<iostream>  6 using namespace std;  7  8 struct A  9 { 10 char a; 11 int b; 12 }; 13 struct B 14 { 15 char a; 16  A a1; 17 char b; 18 }; 19 int _tmain(int argc, _TCHAR* argv[]) 20 { 21 cout<<sizeof(A)<<endl<<sizeof(B); 22 return 0; 23 }

上述程序的输出结果是8和16.

下面结合前面给出的准则具体分析一下。

对于结构体A其基本成员类型有char和int两种,最宽的是int占用4个字节,那么根据准则1,编译器会自动为结果体A分配一个能被4整除的首 地址,A的第一个成员char的首地址就是结构体A的首地址,即偏移量为0,接下来,下一个成员变量int首地址,如果不做处理的话,应该是相对于A的偏 移量是1,这就不满足准则2了,所以编译器开始在char的后面填充3个字节,使得int相对于A的偏移量是4,来满足准则2,然后结构体的总大小就是 1(char)+3(填充)+4(int)=8,同时满足了准则3,不用再填充了,所以sizeof(A)=8。

 对于结构体B,其中包括了一个复合类型,查看基本类型的时候,要将其中的结构体A拆分成char和int两种类型来看,所以结构体B中的基本数据 类型是char,char,int,char,最宽的数据类型是int,编译器会自动为B分配一个能被4整除的首地址,B的第一个成员char的首地址就 是结构体B的首地址,即偏移量为0,接下来,下一个成员变量A的首地址,如果不做处理的话,应该是相对于B的偏移量是1,这就不满足准则2了,所以编译器 开始在char的后面填充3个字节,使得成员A相对于所在结构体B的地址偏移量是4,来满足准则2,这时加上B的长度8,B中最后一个成员char相对于 B来说地址偏移量是8,能满足准则2,所以不需要在A的后面填充字节,这时B的总长度是1(char)+3(填充)+8(A)+1(char)=13,不 满足准则3,所以还需要在最后一个char后面再添加3个字节,最后得到B的总大小是1(char)+3(填充)+8(A)+1(char)+3(填 充)=16,所以sizeof(B)=16。



http://www.cnblogs.com/bewolf/p/4356903.html
发表于 2016-08-28 17:21:56 回复(0)
1、  结构体的大小等于结构体内最大成员大小的整数倍
2、  结构体内的成员的首地址相对于结构体首地址的偏移量是其类型大小的整数倍,比如说double型成员相对于结构体的首地址的地址偏移量应该是8的倍数。
3、  为了满足规则1和2编译器会在结构体成员之后进行字节填充!
发表于 2016-02-25 14:20:50 回复(1)
存储的时候的对齐原则,这个破题。。一直考,一直考。。。
A中,a占4个字节,b本应占2个字节,但由于c占4个字节,为了满足条件: 结构体内的成员的首地址相对于结构体首地址的偏移量是其类型大小的整数倍,比如说double型成员相对于结构体的首地址的地址偏移量应该是8的倍数。 b多占用2个字节,为了满足条件1,d占用4个字节,一共16个字节。
B中,a占8个字节,b占2个字节,但由于c占4个字节,为了满足条件2,b多占用2个字节,
即abc共占用8+4+4=16个字节,
为了满足条件1,d将占用8个字节,一共24个字节。
发表于 2015-09-05 10:24:18 回复(1)
考虑对齐的前提下,GCC编译器不是最高位,默认位数为4.
发表于 2021-02-08 14:48:03 回复(0)
我在64位机器上,系统是ubuntu12.04,gcc版本4.7,运行结果是16 24,所以正确答案是C,不是D。结构体中按照最大变量的那个长度对齐,如果是doule和int都存在,既要4位对齐,又要8位对齐。
编辑于 2019-11-02 11:25:11 回复(0)
内存对齐

1、  对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移量必须是min(#pragma pack()指定的数,这个数据成员的自身长度) 的倍数。
2、  在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。
发表于 2016-08-17 03:43:01 回复(0)
linux下的gcc编译器结果为 20
windows下的VC++结果为 24
发表于 2015-08-22 11:44:44 回复(0)
[root@localhost c++]# ./a.out
16
20
为啥我编译运行的结构为20啊?
我的是32位的编译器!
发表于 2015-06-15 23:13:57 回复(0)
EVL头像 EVL
4字节对齐
A : 4 + 2 + 2 + 4 + 4 =16
B :   2 + 2 + 4 + 1 + 3 = 12
发表于 2022-04-04 22:02:38 回复(0)
结构体A比结构体B所占空间要大,只能选D
发表于 2021-03-07 12:55:25 回复(0)
要根据是32位系统还是64位系统来计算,CPU字长不同结果不同
发表于 2020-08-21 13:16:03 回复(0)
对齐原则是任何K字节的基本对象的地址必须是K的倍数
发表于 2020-02-09 17:09:48 回复(0)
Mac上,Homebrew gcc, 选C.
发表于 2019-11-22 13:20:09 回复(0)
这道题不对吧,不是应该结构体大小等于结构体中最大成员大小的整数倍,class b不应该是8的倍数吗
发表于 2019-09-16 15:31:15 回复(1)
我用g++编译的
发表于 2019-08-08 20:35:44 回复(0)
class C
{
        int a;
        short b;
        int c;
        char d;
};
class D
{
        double a;
        short b;
        int c;
        char d;
};
/*
sun@debian:~/C$ gcc --version
gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


我的结果是C
*/
//编译器gcc,这种没营养的体没有固定答案,编译器依赖
int main()
{
   std::cout<<sizeof( C)<<std::endl;
    std::cout<<sizeof( D)<<std::endl;
}


发表于 2019-02-10 22:10:59 回复(0)
GCC默认4字节对齐,选D。
发表于 2018-11-27 14:49:07 回复(0)