首页 > 试题广场 >

在64位系统上以下描述正确的是?

[单选题]
struct T {
    char a;
    int *d;
    int b;
    int c:16;
    double e;
};
T *p;
在64位系统以及64位编译器下,以下描述正确的是
  • sizeof(p) == 24
  • sizeof(*p) == 24
  • sizeof(p->a) == 1
  • sizeof(p->e) == 4
推荐
字节对齐的三个准则:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。
再来看这道题:
a占一个字节(注:地址为[0]),d作为64位指针占8个字节(注1:32位占四个字节,p也一样)(注2:根据上面的准则2,d的偏移量要为8的整数倍,所以d的地址为[8]-[15],而非[1]-[8],下同),b占了4个字节(注:地址为[16][19]),c指定为16为,占了两个字节(注:地址为[20,21]),e占8个字节,(同d的分析一样,e的地址应该为[24][31]),所以A的答案应该是8,B的答案是32,C正确,D的答案为8。
注:我也是菜,现学现卖!
编辑于 2015-12-25 17:07:49 回复(9)
64位操作系统的地址寻址总线不一定是64位,即使是,在不同编译环境设定中,sizeof只指针的值也不是确定的一个状态,C是确定正确的
发表于 2015-07-24 16:54:32 回复(0)
也许很多同学选择了B,其实,我也选了这个。
但是,看了解析,我才发现,原来自己大意了。
因为,在64位系统下,地址占64位,即指针占64位,8个字节
所以,*p所占的内存是这要的:
a:本身占1个字节,字节对齐占7个字节,共8个字节
d:64位指针,占8字节
b:占32位,4个字节
c:16 :占16位,2个字节,字节对齐占2个字节,共4个字节
e:64位,8个字节

8 + 8 + 4 + 4 + 8 = 32

发表于 2015-08-15 22:03:55 回复(10)
sizeof(p) == 8  P为指针,64位系统地址占8个字节
sizeof(*p) == 24 根据内存对齐  32字节  a_ _ _ _ _ _ _ | * 8字节|  | b4字节|  |c2字节|_ _ |e8字节|
sizeof(p->a) == 1 正确
sizeof(p->e) == 8  double
编辑于 2015-07-29 14:47:55 回复(15)
看了大家的疑惑,就是为什么a那里补了7个字节,c那里却只补了两个字节。
数据成员对齐规则:结构体每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int为4字节,则要从4的整数倍地址开始存储)。
所以,a下面的是*d,*d占8个字节,所以他的起始位置就要是8字节的整数倍,所以a补了7个字节
而对于c,c的起始位置是20,结束位置是22,而c下面的是e,e为8字节,起始位置必须为8的倍数,所以c要补两个字节,结束位置为24即,e的起始位置
发表于 2018-05-11 17:20:28 回复(3)

字节对齐就是让每一个成员的开始地址是最大成员大小的整数倍,本题中最大的成员是e,占了8个字节,所以每一个成员的首地址都要是8的整数倍。
a的首地址是0,是8的整数倍,为了确保后面一个成员开始的地址是8的整数倍,所以要填充7个字节;
经过a的填充,d开始的地址是8的整数倍,不填充;
b开始的地址是16,不需要填充;
c占了2个字节,如果不填充那么下一个成员开始的地址是22,所以需要填充两个字节;
e的首地址是24,本身是8个字节;
所以加起来是32.


发表于 2015-10-06 17:08:03 回复(3)

32位编译器 char :1个字节 char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器) short int : 2个字节 int: 4个字节 unsigned int : 4个字节 float: 4个字节 double: 8个字节 long: 4个字节 long long: 8个字节 unsigned long: 4个字节 64位编译器 char :1个字节 char*(即指针变量): 8个字节 short int : 2个字节 int: 4个字节 unsigned int : 4个字节 float: 4个字节 double: 8个字节 long: 8个字节 long long: 8个字节 unsigned long: 8个字节

发表于 2015-08-22 10:32:31 回复(0)
发表于 2016-08-28 13:54:16 回复(0)
关于结构体和联合的字节对齐原则:http://www.cnblogs.com/fly1988happy/archive/2012/04/12/2444408.html
另外,在64位系统中,指针占8个字节
发表于 2016-06-17 10:39:56 回复(0)
a占一个字节(注:地址为[0]),d作为64位指针占8个字节(注1:32位占四个字节,p也一样)(注2:根据上面的准则2,d的偏移量要为8的整数倍,所以d的地址为[8]-[15],而非[1]-[8],下同),b占了4个字节(注:地址为[16][19]),c指定为16为,占了两个字节(注:地址为[20,21]),e占8个字节,(同d的分析一样,e的地址应该为[24][31])
我补充下为啥22 23没有,因为数据类型的存储地址必须是自身数据类型的整数倍,按照数据类型的顺序到21,而double为8字节,所以必须是24起步,22存不了,就像第一个是地址0第二个是指针8字节,起步必须地址是8,根据数据类型定义的顺序。

发表于 2020-06-06 11:01:57 回复(0)
题目前提:在64位系统以及64位编译器下,也就是说地址大小(长度)是8个字节:8(bits = 1Bytes)*8 = 64bits
p是指针,指向struct T在内存中的首地址,64位,8个字节
由于在内存中需要字节对齐,所以,*p所占的内存是这要的:
a:char类型,1个字节,字节对齐需要7个字节,占8个字节
d:int类型指针,64位指针,占8字节
b:int类型,数值,32位,4个字节
c:16 :int16,占16位,2个字节,字节对齐占2个字节,共4个字节
e:double类型,64位,8个字节
8 + 8 + 4 + 4 + 8 = 32
sizeof(p) = 8
sizeof(*p) = 32
sizeof(p->a) = 1
sizeof(p->e) = 8

发表于 2018-11-12 15:03:13 回复(0)
为什么吃c不要求是8的倍数
发表于 2015-12-05 12:24:26 回复(0)
因为, 在64位系统下,地址占64位 ,即指针占64位,8个字节。
所以,*p所占的内存是这要的:
a:本身占1个字节,字节对齐占7个字节,共8个字节
d:64位指针,占8字节
b:占32位,4个字节
c:16 :占16位,2个字节,字节对齐占2个字节,共4个字节
e:64位,8个字节

8 + 8 + 4 + 4 + 8 = 32
编辑于 2015-08-22 16:38:01 回复(0)
sizeof(*p)在64位的机器上,使用32位的编译器结果是24,使用64位的编译器结果是32
发表于 2015-07-27 11:43:45 回复(0)
一般变量在X86和X64系统下长度没什么区别,区别在于指针的 寻址范围从32位增加到了64位
p在这里是一个指针变量 所以只计算指针的大小长度 为8个字节 所以A正确
我的感觉是c也正确,在64位机器上 char型变量就是一个字节长度的 留待大神解答

发表于 2015-04-14 13:54:03 回复(2)
A 64位系统的指针大小为8 
发表于 2015-01-06 17:57:17 回复(0)

为什么C的首地址可以不是 $8$ 的倍数?感觉在逗我

发表于 2018-02-13 17:55:43 回复(0)
这个题说明,即使是对其了,char也只占1个字节,后面那3个字节浪费掉不用,都不给你用,,,
发表于 2016-11-15 10:14:39 回复(0)
8+8+(4+4)+8=32
发表于 2023-10-01 23:04:12 回复(0)
1(7)842(2)8
发表于 2022-04-06 12:25:53 回复(0)
因为,在64位系统下,地址占64位,即指针占64位,8个字节 所以,*p所占的内存是这要的: a:本身占1个字节,字节对齐占7个字节,共8个字节 d:64位指针,占8字节 b:占32位,4个字节 c:16 :占16位,2个字节,字节对齐占2个字节,共4个字节 e:64位,8个字节 8 + 8 + 4 + 4 + 8 = 32 我还以为 内存对齐 是对最后所有占有字节再进行对齐 看来是遇到下一个对齐的元素停止
发表于 2021-10-26 13:32:58 回复(0)