首页 > 试题广场 >

如果Data的地址是x,那么data[1][5].c的地址是

[单选题]
struct Date
{
    char a;
    int b;
    int64_t c;
    char d;
};
Date data[2][10];
在64位系统上,如果Data的地址是x,那么data[1][5].c的地址是()
  • X+195
  • X+365
  • X+368
  • X+215
推荐

我觉得C

结构体成员地址对齐
a               b  c  d
1+(3)+4+8+1+(7)= 24,()内表示为了满足对齐填充的大小。
&data[1][5].c = x+10*24+5*25+1+(3)+4=368。 
编辑于 2015-01-26 21:11:14 回复(21)
1、结构体所占的内存大小:
a.整体所占的内存大小应该是结构中成员类型最大的整数倍,此处最大的类型是int_64t,占8个字节。。即最后所占字节的总数应该是8的倍数,不足的补足;
b.数据对齐原则-内存按结构体成员的先后顺序排列,当排到该成员变量时,其前面所有成员已经占用的空间大小必须是该成员类型大小的整数倍,如果不够,则前面的成员占用的空间要补齐,使之成为当前成员类型的整数倍。假设是地址是从0开始,结构体中第一个成员类型char型占一个字节,则内存地址0-1,第二个成员从2开始,int型所占内存4个字节,根据原则b,第一个成员所占内存补齐4的倍数,故第一个成员所占内存:1 + 3 = 4; 第二个成员占5-8. 第三个成员占8个字节,满足原则b,不需要补齐,占9-16.  第四个成员占一个字节,占17. 故总内存为1 + 3 + 4 + 8 + 1 = 17个字节,但根据原则a,总字节数需是8的倍数,需将17补齐到24.  故此结构体总字节数为:24字节

2、计算
data[1][5],意思是前面有15个元素。则第15个元素的起始地址为: 24 * 15 = 360, 即 X + 360
则data[1][5].c的地址为: 360 + 1 + 3 + 4 = 368,即 X + 368
发表于 2017-08-08 22:24:43 回复(6)
按8位对齐,(a+b)=5+(3)->8,d=1+(7)->8,所以结构体的大小为8+8+8=24,data[1][5]=x+15*24,
data[1][5].c=x+15*24+5+(3)=x+368.
编辑于 2015-07-03 16:07:33 回复(4)
题目本身就有问题,并未说清楚编译平台,也没有说清楚是在32位还是在64位操作系统下。我在linux的gcc上测试,在32位操作系统下Date占用20字节,64位下占用24字节,不同点在于变量d后字节对齐的字节数,32位操作系统下向4字节对其,需填充3字节,64位下需要填充7个字节。

这里假定系统为64位的gcc平台,data[1][5]与data[0][0]相隔15个元素,data[1][5]地址为x + sizeof(Date) * 15 = x + 360。变量c位于结构体的第8个位置。

选C
发表于 2015-01-20 11:27:45 回复(8)
上面这些讨论所针对的题目和现在看到的题目不大一样,题目应该被修改过。
这道题关键分歧点在于内存对齐模数上。
原题目应该没有写32位还是64位,当然更没有说是win-32、linux-32、还是linux-64。所以大多数讨论都默认按64位处理,得到对齐模数为8,于是就有C选项正确。
但是!现在题目改了,明确说是32位系统!32位系统默认对齐模数是4,4小于结构体内部最大的基本数据类型成员的对齐模数(int64_t: 8)。所以,该结构体的内存对齐模数是4! 该结构体的内存对齐模数是4! 该结构体的内存对齐模数是4!不是8!
结构体的size为:1 (+ 3)+ 4 + 8 + 1 (+ 3) = 20 ;
data[1][5].c的地址为:x + 20 * 15 + 1 ( + 3) + 4 = x + 308
ABCD都不对!

关于不同平台的基本数据类型成员的对齐模数,请参考:http://www.cnblogs.com/motadou/archive/2009/01/17/1558438.html
编辑于 2016-07-30 16:45:11 回复(8)
发表于 2021-06-28 21:15:45 回复(2)
如果不考虑结构体占用内存的对称性,占用情况如下:
struct Date
{
    chara;  //需要1个字节
    intb;   //需要 4个字节
    int64_t c;//需要8个字节
    chard;  //需要1个字节
};
但是实际情况如下
a+b 占用8个字节
c   占用8个字节
d   占用8个字节
于是结构体占用内存是24字节
data[1][5].c,前面有15个结构体占用字节+a和b占用字节
故占用字节为:24 *15+8=368。

发表于 2016-04-18 11:46:57 回复(2)
选C,解析如下:
char a 是1个字节,8位长度,一个内存寻址单元是4个字节,空三个字节,占用一个内存单元
int b 是4个字节,32位长度,占满一个内存单元
int64_t c 是8个字节,64位长度,占满两个内存单元
char d 是1个字节,8位长度,后面的三个字节是空的,占用一个内存单元
目前为止总共是5个内存单元,需要再加一个内存单元,以保证结构体整体占用数是int64_t的整数倍。
因此一个结构体占用了6个内存单元,为24个字节。
由于是从data[0][0]开始计数的,因此data[1][5]是第16个结构体,前面排满了15个一样的结构体。求的是第16个结构体中第三个参数c的位置,因此与Data的第一个地址相差15*24+8=368个字节。
发表于 2016-03-21 14:42:28 回复(1)
首先结构体是内存要对齐的
从题上来说是默认
#pragram  pack(8) (64位的机器)

所以内存对齐1+(3)+4+8+1  为了满足时最大的变量(这里是int64c  8个字节)的字节数与pack(8)相比其中最小的就是8的倍数所以再补上7个字节就是24个字节
对于这个二维的结构体数组  data[1][5]在数组的第二行的第五个所以地址就是 x +第一行列数*结构体大小再加上第二行的5列*结构体大小
就是 10 *24 + 5*24 =360  下来计算这个 .c的地址 就是内存对齐时候算过的 1+(3)+4=8 所以总的就是x+360+8=x+368
所以选择C
发表于 2015-08-10 13:44:21 回复(2)
内存对齐三大原则:

  • 结构体的各个成员,第一个成员的偏移量是0,排列在后面的成员其当前偏移量必须是当前成员类型的整数倍
  • 结构体内所有数据成员各自内存对齐后,结构体本身还要进行一次内存对齐,保证整个结构体占用内存大小是结构体内最大数据成员的最小整数倍
  •  如程序中有#pragma pack(n)预编译指令,则所有成员对齐以n字节为准(即偏移量是n的整数倍),不再考虑当前类型以及最大结构体内类型

数组偏移:
A[M][N]
A[i][j]  ->  i*N+j  ->1*10+5 = 15
结果:(1+3+4+8+1+7)*15+8 = 368


发表于 2019-11-29 20:13:44 回复(0)

注意是.c的地址

发表于 2019-01-04 14:10:17 回复(1)
每个元素占1(+3)+4+8+1(+8) = 24个字节
data[1][5]元素前面有15个元素,故data[1][5]地址为24*15=360,而data[1][5].c地址为360+8=368。
发表于 2018-03-06 20:05:26 回复(0)
1+(3)(除非数组,否则补齐4字节,32位里面默认的,也可自行设置为其他值)+4+8+1+(3+4)(本来要补齐4,则加3,但是违反了最终内存为最大元素空间8整数倍,本来是20,20取8的模不为0,那么商加1则取3个8的空间,即24),24*15=360,前面8个字节,所以是368为c的起始地址
发表于 2016-11-05 10:12:00 回复(0)
32位编译器(codeblocks)运行情况(机器是64位机)。
发表于 2016-08-23 11:42:58 回复(2)
32位机
sizeof(char) =1
sizeof(int) =4
sizeof(int64_t) = 8
结构体成员地址对齐    以最大字节数(2的倍数)对齐
这里以int64_t 字节对齐
&data[0][9] = x+10*24
&data[1][5] = 5*24
&data[1][5].c = 1+3+4
=240+120+8
=368
发表于 2016-06-15 16:51:59 回复(2)
首先得对齐:为什么要对齐,这是时间空间的一个抉择,对齐的效率会更快,我们来讲讲对齐
struct Date
{
    chara;
    intb;
    int64_t c;
    chard;
};
首先第一个是char肯定得对齐1个字节的,int肯定对齐在4的位置,因为大小为4,c大小为8,d同理要补成8的整数,因为最大的成员大小是8
0 1 2 3 4 5 6 7 8 9 10 ... 15 16 17 18 19 20 21 22 23
a a a a b b b b c c c    ... c    d  d    d   d   d  d    d  d
所以总的大小是24,接着就好计算了10*24+5*24+1+3+4=368
编辑于 2015-09-03 17:14:22 回复(0)
C
结构体大小为所有数据大小和
1+(3)+4+8+1+(7)= 24
Date data[2][10];
是一个2行10列的结构体数组
发表于 2015-01-26 20:09:30 回复(0)
主要考int64_t这个数据类型为64位
发表于 2022-04-08 22:20:22 回复(0)
题目出的不清晰,估计应该是说的32位平台。
发表于 2016-08-22 19:40:59 回复(0)
人家说了32位,你们还按64?
发表于 2015-09-30 15:03:32 回复(1)
数据对齐需要考虑如下: 1.数据类型自身的对齐值:就是上面交代的基本数据类型的自身对齐值。 2.指定对齐值:#progma pack (value)时的指定对齐值value。 3.结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。 4. 数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个值。

struct Date { char a;//起始位置0 int b;//起始位置4 int64_t c;//起始位置8 char d;//起始位置16,因4字节对齐,所以到位置20结束  };
考虑成员中自身对齐值最大的那个值 是8.  20不是8的倍数,
所以这个sturct的size是24.
所以 data[1][5].c的地址是x+24*15+(4+4) = 368

答案 选 C
编辑于 2015-04-03 17:29:37 回复(1)