一个笔试题目

时间:2021-10-12 14:40:51
在对齐为4的情况下

struct BBB
{
long num;
char *name;
short int data;
char ha;;
(Ulong)p+0x200=____;
(char*)p+0x200=____;
short ba[5];
}*p;
p=0x1000000;
p+0x200=____;
(Ulong)p+0x200=____;
(char*)p+0x200=____;

53 个解决方案

#1


更正:

struct BBB
{
long num;
char *name;
short int data;
char ha;;
short ba[5];
}*p;
p=0x1000000;
p+0x200=____;
(Ulong)p+0x200=____;
(char*)p+0x200=____;

#2


楼主自己运行下啊....  只要知道sizeof(struct BBB)怎么算,应该就能做对了~~

#3


upup一下

#4


给你一个类似参考:
 struct BBB 

  int lNum; 
  char *pcName; 
  short sDate; 
  char cha[2]; 
  short sBa[4]; 
}*p; 
p = 0x100000; 

p + 0x1 = 0x100014  指针相加 加结构体的大小 

(unsigned long)p + 0x1 = 0x100001 强制转换为ulong 
(unsigned int*)p + 0x1 = 0x100004  加一个unsigned int的大小即可 

#5


引用 4 楼 chenzhp 的回复:
C/C++ code给你一个类似参考:
 struct BBB 

  int lNum; 
  char *pcName; 
  short sDate; 
  char cha[2]; 
  short sBa[4]; 
}*p; 
p = 0x100000; 

p + 0x1 = 0x100014  指针相加 加结构体的大小 

(unsigned long)p + 0x1 = 0x100001 强制转换为ulong 
(unsigned int*)p + 0x1 = 0x100004  加一个unsigned int的大小即可 


up

#6


在数值上分别是:
0x1003000
0x1000200
0x1000200

BBB:
4
1 X   因为data的偏移地址要能被2整除
2
1 XXX 后面那个数组大小超过4字节了,所以根据对齐为4,这里只填充3
10 XX    整体大小对齐到12

于是sizeof(BBB) = 24

p + 0x200 = p本身的值 + sizeof(BBB) * 0x200 = 0x1003000
(结果类型是BBB*)
(Ulong)p+0x200 = 0x1000200.这是整数加法
(结果类型是Ulong)
(char*)p+0x200 = p本身的值 + sizeof(c) * 0x200 = 0x1000200
(结果类型是char*)

#7


引用 4 楼 chenzhp 的回复:
C/C++ code给你一个类似参考:
 struct BBB 

  int lNum; 
  char *pcName; 
  short sDate; 
  char cha[2]; 
  short sBa[4]; 
}*p; 
p = 0x100000; 

p + 0x1 = 0x100014  指针相加 加结构体的大小 

(unsigned long)p + 0x1 = 0x100001 强制转换为ulong 
(unsigned int*)p + 0x1 = 0x100004  加一个unsigned int的大小即可 
为什么(unsigned long)p + 0x1 = 0x100001 不加一个unsigned long的大小? 

#8


晕,最后两个是因为sizeof(BBB)要被最大的成员整除加上去的...
22调整到被4整除.

#9


前面的指针+,没什么难度。

p+0x200,就是p偏移sizeof(p)*0x200.

所以要根据字节对齐判断p结构的size.

字节对齐,你看我这篇的3原则,很容易把握的。

http://blog.csdn.net/hairetz/archive/2009/04/16/4084088.aspx

1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。

 

2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)

 

3:收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补齐.

#10


学习

#11


学习了~~~~

#12


引用 9 楼 hairetz 的回复:
前面的指针+,没什么难度。 

p+0x200,就是p偏移sizeof(p)*0x200. 

所以要根据字节对齐判断p结构的size. 

字节对齐,你看我这篇的3原则,很容易把握的。 

http://blog.csdn.net/hairetz/archive/2009/04/16/4084088.aspx 

1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节…

p+0x200,就是p偏移sizeof(p)*0x200. 
你又写错了
p+0x200,就是p偏移sizeof(*p)*0x200. 

#13


引用 7 楼 sayigood 的回复:
引用 4 楼 chenzhp 的回复: 
 C/C++ code给你一个类似参考: 
  struct BBB  
 {  
   int lNum;  
   char *pcName;  
   short sDate;  
   char cha[2];  
   short sBa[4];  
 }*p;  
 p = 0x100000;  
  
 p + 0x1 = 0x100014  指针相加 加结构体的大小  
  
 (unsigned long)p + 0x1 = 0x100001 强制转换为ulong  
 (unsigned int*)p + 0x1 = 0x100004  加一个unsigned int的大小即可  
  
 为什么(unsigned long)p + 0x1 …
如果0x1是unsigned long类型的话,那么(unsigned int*)p + 0x1是不是结果也为0x100001,因为unsigned int*与0x1都是4byte?

#14


0x01的类型是按int, unsigned int, long it, unsigned long int序列,能被首先装下的类型.

#15


引用 6 楼 baihacker 的回复:
C/C++ code在数值上分别是:
0x1003000
0x1000200
0x1000200

BBB:
4
1 X   因为data的偏移地址要能被2整除
2
1 XXX 后面那个数组大小超过4字节了,所以根据对齐为4,这里只填充3
10 XX    整体大小对齐到12

于是sizeof(BBB) = 24

p + 0x200 = p本身的值 + sizeof(BBB) * 0x200 = 0x1003000
(结果类型是BBB*)
(Ulong)p+0x200 = 0x1000200.这是整数加法
(结果类型是Ulong)
(char*)p+0x200 = p本身的值 + sizeof(…


up 

#16


明白人,继续啊

#17


要考虑字节对齐吗?

#18


在数值上分别是:
0x1003000
0x1000200
0x1000200

BBB:
4
1 X   因为data的偏移地址要能被2整除  //这应该是4吧??
2
1 XXX 后面那个数组大小超过4字节了,所以根据对齐为4,这里只填充3
10 XX    整体大小对齐到12

于是sizeof(BBB) = 24

p + 0x200 = p本身的值 + sizeof(BBB) * 0x200 = 0x1003000
(结果类型是BBB*)
(Ulong)p+0x200 = 0x1000200.这是整数加法
(结果类型是Ulong)
(char*)p+0x200 = p本身的值 + sizeof(c) * 0x200 = 0x1000200
(结果类型是char*)

///////////

在对齐为4的情况下 
struct BBB
{
long num;  4
char *name; 4
short int data; 2
char ha;;  1+1
short ba[5]; 2*5
}*p;


sizeof(BBB) = 22+2= 24//4的整数倍
p=0x1000000;
p+0x200=____;    
(Ulong)p+0x200=____;
(char*)p+0x200=____;

#19


引用 12 楼 baihacker 的回复:
p+0x200,就是p偏移sizeof(p)*0x200. 
你又写错了 
p+0x200,就是p偏移sizeof(*p)*0x200. 



一个笔试题目
经常笔误的。。
急性子的人,没办法。飞雪那个又字,我好伤心啊。

应该是你又*n写错了。。
一个笔试题目

#20


引用 1 楼 sayigood 的回复:
更正: 

C/C++ code
struct BBB
{
long num;
char *name;
short int data;
char ha;;
short ba[5];
}*p;
p=0x1000000;
p+0x200=_ 0x1000000+0x200*sizeof(BBB)___;
(Ulong)p+0x200=__0x100000+0x200;
(char*)p+0x200=__0x100000+0x200*sizeof(char)__;

#21


唉……

#22


我觉得你可以自己学习一个内存对齐那一块,然后算出结果让大家来讨论……比这样说着强。

楼上已经有解释得明明白白的了。

#23


引用 6 楼 baihacker 的回复:
C/C++ code在数值上分别是:
0x1003000
0x1000200
0x1000200

BBB:
4
1 X   因为data的偏移地址要能被2整除
2
1 XXX 后面那个数组大小超过4字节了,所以根据对齐为4,这里只填充3
10 XX    整体大小对齐到12

于是sizeof(BBB) = 24

p + 0x200 = p本身的值 + sizeof(BBB) * 0x200 = 0x1003000
(结果类型是BBB*)
(Ulong)p+0x200 = 0x1000200.这是整数加法
(结果类型是Ulong)
(char*)p+0x200 = p本身的值 + sizeof(…

sizeof(BBB)=24是对的,但上面的BBB大小的分析过程(红色部分),兄弟看得不是很明白,我是这么理解的:

struct BBB
{
   long num;                  // 4bytes
   char *name;               // 4bytes (在32bit操作系统上,指针是4bytes的)
   short int data;           // 2bytes
   char ha;                  // 1byte
   short ba[5];              // 5 * 2 = 10 bytes
}*p;

因此加起来应该是21bytes,考虑到内存对齐的因素,调整为24bytes。

关于内存对齐的详细解释,请见: 关于内存对齐问题

#24


这个问题的关键还是内存对齐问题, 关于内存对齐问题这篇文章给出了详细的解释,文中是以class来解释内存对齐问题的,同样也适用与struct。

#25


引用 6 楼 baihacker 的回复:
C/C++ code在数值上分别是:0x10030000x10002000x1000200BBB:41X   因为data的偏移地址要能被2整除21XXX 后面那个数组大小超过4字节了,所以根据对齐为4,这里只填充310XX    整体大小对齐到12

于是sizeof(BBB)=24p+0x200=p本身的值+sizeof(BBB)*0x200=0x1003000(结果类型是BBB*)
(Ulong)p+0x200=0x1000200.这是整数加法
(结果类型是Ulong)
(char*)p+0x200=p本身的值+sizeof(c)*0x200=0x1000200(结果类型是char*)


飞雪你这块儿对struct BBB的计算好像有问题!
我觉得应该是这样的:
(4) + (4)+ (2+<补2>)+(1+<补3>)+(5+<补3>) 
我不晓得你的24是怎么算出来的,结果到真是24!

另外还有你的这里:
(Ulong)p+0x200 = 0x1000200.这是整数加法
(结果类型是Ulong)
我觉得(Ulong)类型的大小应该是4,所以(Ulong)p+0x200 = p本身的值+sizeof(Ulong)*0x200

请飞雪和其他看官明鉴!

#26



汗!
陷阱,粗心了,25楼我的回复中,没有看清楚
(Ulong)p+0x200
不是:
(Ulong*)p+0x200
对不起各位啦!

#27


25楼的short为1byte么?这个不对。sizeof(short)=2bytes的。

请再参考: 再谈内存对齐问题

#28


再指出25楼的问题,内存对齐根本不是你那样算的,如果按照你的算法,下面结构(增加了char hb)的大小应该是28了,而事实上仍然是24bytes。

struct BBB
{
long num;
char *name;
short int data;
char ha;
char hb;
short ba[5];
}*p;


所谓内存对齐看的是整个对象是否内存对齐,而不是看对象中某个具体的成员是否内存对齐。

#29


引用 27 楼 pathuang68 的回复:
25楼的short为1byte么?这个不对。sizeof(short)=2bytes的。

请再参考:再谈内存对齐问题

再汗!pathuang68说的一针见血啊!搞得我大热天,虽有开空调,还直冒汗!

(4)+(4)+(2)+(1+<补1>)+(10)+<补2>

飞雪兄,对不住啦!

#30


引用 29 楼 insulted 的回复:
引用 27 楼 pathuang68 的回复:
25楼的short为1byte么?这个不对。sizeof(short)=2bytes的。 

请再参考:再谈内存对齐问题 
 
再汗!pathuang68说的一针见血啊!搞得我大热天,虽有开空调,还直冒汗! 

(4)+(4)+(2)+(1+ <补1>)+(10)+ <补2> 

飞雪兄,对不住啦!

偶尔言中罢了。
哥们,你咋还那样去补齐呀,看看28楼的红色字体部分。

#31


呵呵 内存对齐的问题 还考了几个加法 一个笔试题目

#32


主要还是结构体内存对齐与指针相加问题
http://www.cppblog.com/iuranus/archive/2009/01/06/71388.html

#33


引用 27 楼 pathuang68 的回复:
25楼的short为1byte么?这个不对。sizeof(short)=2bytes的。 

请再参考:再谈内存对齐问题


顶玄机逸士的贴子!

#34


引用 28 楼 pathuang68 的回复:
再指出25楼的问题,内存对齐根本不是你那样算的,如果按照你的算法,下面结构(增加了char hb)的大小应该是28了,而事实上仍然是24bytes。 

C/C++ code
    struct BBB
    {
        long num;
        char *name;
        short int data;
        char ha;
        char hb;
        short ba[5];
    }*p;




所谓内存对齐看的是整个对象是否内存对齐,而不是看对象中某个具体的成员是否内存对齐。

那么这个呢?
struct BBB{
   char ha;
   char *name;
   char hb;
};

#35


引用 30 楼 pathuang68 的回复:
引用 29 楼 insulted 的回复:
引用 27 楼 pathuang68 的回复: 
25楼的short为1byte么?这个不对。sizeof(short)=2bytes的。 

请再参考:再谈内存对齐问题 

再汗!pathuang68说的一针见血啊!搞得我大热天,虽有开空调,还直冒汗! 

(4)+(4)+(2)+(1+ <补1>)+(10)+ <补2> 

飞雪兄,对不住啦! 
 
偶尔言中罢了。 
哥们,你咋还那样去补齐呀,看看28楼的红色字体部分。

大意了!insulted兄这样的 (4)+(4)+(2)+(1+ <补1>)+(10)+ <补2> 是正确的,特此致歉!

#36


引用 34 楼 ltc_mouse 的回复:
引用 28 楼 pathuang68 的回复:
再指出25楼的问题,内存对齐根本不是你那样算的,如果按照你的算法,下面结构(增加了char hb)的大小应该是28了,而事实上仍然是24bytes。 
C/C++ code 
    struct BBB 
    { 
        long num; 
        char *name; 
        short int data; 
        char ha; 
        char hb; 
        short ba[5]; 
    }*p; 

所谓内存对齐看的是整个对象是否内存对齐,而不是看对象…

那么这个呢? 
struct BBB{ 
  char ha; 
  char *name; 
  char hb; 
};

写ltc_mouse兄指正,我想我应该要修改“所谓内存对齐看的是整个对象是否内存对齐,而不是看对象中某个具体的成员是否内存对齐。”这种说法,以免误会。

至于你说到的:

struct BBB

  char ha; 
  char *name; 
  char hb; 
};

因为ha和hb不相邻,中间隔着char* name,因此sizeof(BBB) = [1 + (补3)] + 4 + [1 + (补3)] = 12bytes。这样看起来好像是分别补齐了ha和hb到4bytes。

而下面的代码:

struct BBB

  char *name; 
  char ha;
  char hb; 
};

ha和hb相邻,因此sizeof(BBB) = 4 + [2 + (补2)] = 8bytes。
这样看起来并不是分别补齐ha和hb。

基于这样的原因,我使用了“所谓内存对齐看的是整个对象是否内存对齐,而不是看对象中某个具体的成员是否内存对齐。”这样的说法,现在想来确有不妥,但用一句话也不太好表达,准备写一篇博文以正之。

#37


真理越辩越明,诚哉斯言!

#38


大概看了一下。

4楼和6楼已经给出明确的答案了。

就是一个是指针加法,还是数值加法的问题了。

指针加法,加出来的是指针类型的字节长度的整倍数。
数值加法……那就是有多少加多少了!

像楼主问的,为什么(ulong)p + 0x1 不是加一个ulong的大小……

因为,经过ulong后,这已经不再是指针加法,而变成一个数值加法了,就好像问你 1+1等于几,你不可能得出2以外的结果吧。

楼主你要问的是 (ulong*)p + 0x1 的事儿……别混了

完毕。

#39


最后,对齐为 4与结构体内“最长基本数据类型”的长度(为4)不冲突,所以不用考虑这个值。但若结构体内有一个double型成员的话……就要考虑这个 4 了。

具体的类似问题,上网查吧,就查“数据对齐”,有的是文章,随便看一篇就全明白了!

#40


学习中……

#41


学习了~

#42


引用 38 楼 hikaliv 的回复:
大概看了一下。 

4楼和6楼已经给出明确的答案了。 

就是一个是指针加法,还是数值加法的问题了。 

指针加法,加出来的是指针类型的字节长度的整倍数。 
数值加法……那就是有多少加多少了! 

像楼主问的,为什么(ulong)p + 0x1 不是加一个ulong的大小…… 

因为,经过ulong后,这已经不再是指针加法,而变成一个数值加法了,就好像问你 1+1等于几,你不可能得出2以外的结果吧。 

楼主你要问的是 (ulong*)p + …

6楼那个size分析应该是不正确的。

#43


6 楼分析无误。

#44


我来学习的

#46


内存对齐的话,windows的VS等编译器和GCC的规则是不一眼的,GCC下最多是4,且有压缩什么的

#47


http://www.ksarea.com/articles/20071004_sizeof-struct-memory.html

#48


楼上的高手们都说了。大家看看内存布局就知道了(VS2008)

1>class BBB size(24):
1> +---
1> 0 | num
1> 4 | name
1> 8 | data
1>10 | ha
1>   | <alignment member> (size=1)
1>12 | ba
1>   | <alignment member> (size=2)
1> +---

#49


出这道题的人根本就不懂什么是C语言嘛。
大概没用用过64位的鸡鸡。

$ cat fuck.c && touch fuck.c && make fuck && ./fuck && uname -a
#include <stdio.h>

struct BBB
{
        long num;
        char *name;
        short int data;
        char ha;
        short ba[5];
}*p;

int
main(void)
{
        printf("%lu\n", (unsigned long)sizeof(struct BBB));
        return 0;
}
cc -D_REENTRANT  fuck.c -lpthread -o fuck
32
FreeBSD freebsd.unix-center.net 6.2-RELEASE FreeBSD 6.2-RELEASE #0: Fri Jan 12 08:43:30 UTC 2007     root@portnoy.cse.buffalo.edu:/usr/obj/usr/src/sys/SMP  amd64

#50



$ touch love.c && cat love.c with_you.h && (make love ) && ./love && uname -a && file love                         
#include <stdio.h>

#include "with_you.h"

struct BBB
{
        long num;
        char *name;
        short int data;
        char ha;
        short ba[5];
}*p;

int
main(void)
{
        printf("%lu\n", (unsigned long)sizeof(struct BBB));
        return 0;
}
#pragma pack(1)
cc    -o love love.c 
21
SunOS t1000 5.10 Generic_118833-33 sun4v sparc SUNW,Sun-Fire-T1000 Solaris
love:           ELF 32-bit MSB executable SPARC32PLUS Version 1, V8+ Required, dynamically linked, not stripped
$ touch love.c && cat love.c with_you.h && (CFLAGS='-fast -xarch=v9' make love ) && ./love && uname -a && file love
#include <stdio.h>

#include "with_you.h"

struct BBB
{
        long num;
        char *name;
        short int data;
        char ha;
        short ba[5];
}*p;

int
main(void)
{
        printf("%lu\n", (unsigned long)sizeof(struct BBB));
        return 0;
}
#pragma pack(1)
cc -fast -xarch=v9   -o love love.c 
couldn't set locale correctly
29
SunOS t1000 5.10 Generic_118833-33 sun4v sparc SUNW,Sun-Fire-T1000 Solaris
love:           ELF 64-bit MSB executable SPARCV9 Version 1, dynamically linked, not stripped

#1


更正:

struct BBB
{
long num;
char *name;
short int data;
char ha;;
short ba[5];
}*p;
p=0x1000000;
p+0x200=____;
(Ulong)p+0x200=____;
(char*)p+0x200=____;

#2


楼主自己运行下啊....  只要知道sizeof(struct BBB)怎么算,应该就能做对了~~

#3


upup一下

#4


给你一个类似参考:
 struct BBB 

  int lNum; 
  char *pcName; 
  short sDate; 
  char cha[2]; 
  short sBa[4]; 
}*p; 
p = 0x100000; 

p + 0x1 = 0x100014  指针相加 加结构体的大小 

(unsigned long)p + 0x1 = 0x100001 强制转换为ulong 
(unsigned int*)p + 0x1 = 0x100004  加一个unsigned int的大小即可 

#5


引用 4 楼 chenzhp 的回复:
C/C++ code给你一个类似参考:
 struct BBB 

  int lNum; 
  char *pcName; 
  short sDate; 
  char cha[2]; 
  short sBa[4]; 
}*p; 
p = 0x100000; 

p + 0x1 = 0x100014  指针相加 加结构体的大小 

(unsigned long)p + 0x1 = 0x100001 强制转换为ulong 
(unsigned int*)p + 0x1 = 0x100004  加一个unsigned int的大小即可 


up

#6


在数值上分别是:
0x1003000
0x1000200
0x1000200

BBB:
4
1 X   因为data的偏移地址要能被2整除
2
1 XXX 后面那个数组大小超过4字节了,所以根据对齐为4,这里只填充3
10 XX    整体大小对齐到12

于是sizeof(BBB) = 24

p + 0x200 = p本身的值 + sizeof(BBB) * 0x200 = 0x1003000
(结果类型是BBB*)
(Ulong)p+0x200 = 0x1000200.这是整数加法
(结果类型是Ulong)
(char*)p+0x200 = p本身的值 + sizeof(c) * 0x200 = 0x1000200
(结果类型是char*)

#7


引用 4 楼 chenzhp 的回复:
C/C++ code给你一个类似参考:
 struct BBB 

  int lNum; 
  char *pcName; 
  short sDate; 
  char cha[2]; 
  short sBa[4]; 
}*p; 
p = 0x100000; 

p + 0x1 = 0x100014  指针相加 加结构体的大小 

(unsigned long)p + 0x1 = 0x100001 强制转换为ulong 
(unsigned int*)p + 0x1 = 0x100004  加一个unsigned int的大小即可 
为什么(unsigned long)p + 0x1 = 0x100001 不加一个unsigned long的大小? 

#8


晕,最后两个是因为sizeof(BBB)要被最大的成员整除加上去的...
22调整到被4整除.

#9


前面的指针+,没什么难度。

p+0x200,就是p偏移sizeof(p)*0x200.

所以要根据字节对齐判断p结构的size.

字节对齐,你看我这篇的3原则,很容易把握的。

http://blog.csdn.net/hairetz/archive/2009/04/16/4084088.aspx

1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。

 

2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)

 

3:收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补齐.

#10


学习

#11


学习了~~~~

#12


引用 9 楼 hairetz 的回复:
前面的指针+,没什么难度。 

p+0x200,就是p偏移sizeof(p)*0x200. 

所以要根据字节对齐判断p结构的size. 

字节对齐,你看我这篇的3原则,很容易把握的。 

http://blog.csdn.net/hairetz/archive/2009/04/16/4084088.aspx 

1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节…

p+0x200,就是p偏移sizeof(p)*0x200. 
你又写错了
p+0x200,就是p偏移sizeof(*p)*0x200. 

#13


引用 7 楼 sayigood 的回复:
引用 4 楼 chenzhp 的回复: 
 C/C++ code给你一个类似参考: 
  struct BBB  
 {  
   int lNum;  
   char *pcName;  
   short sDate;  
   char cha[2];  
   short sBa[4];  
 }*p;  
 p = 0x100000;  
  
 p + 0x1 = 0x100014  指针相加 加结构体的大小  
  
 (unsigned long)p + 0x1 = 0x100001 强制转换为ulong  
 (unsigned int*)p + 0x1 = 0x100004  加一个unsigned int的大小即可  
  
 为什么(unsigned long)p + 0x1 …
如果0x1是unsigned long类型的话,那么(unsigned int*)p + 0x1是不是结果也为0x100001,因为unsigned int*与0x1都是4byte?

#14


0x01的类型是按int, unsigned int, long it, unsigned long int序列,能被首先装下的类型.

#15


引用 6 楼 baihacker 的回复:
C/C++ code在数值上分别是:
0x1003000
0x1000200
0x1000200

BBB:
4
1 X   因为data的偏移地址要能被2整除
2
1 XXX 后面那个数组大小超过4字节了,所以根据对齐为4,这里只填充3
10 XX    整体大小对齐到12

于是sizeof(BBB) = 24

p + 0x200 = p本身的值 + sizeof(BBB) * 0x200 = 0x1003000
(结果类型是BBB*)
(Ulong)p+0x200 = 0x1000200.这是整数加法
(结果类型是Ulong)
(char*)p+0x200 = p本身的值 + sizeof(…


up 

#16


明白人,继续啊

#17


要考虑字节对齐吗?

#18


在数值上分别是:
0x1003000
0x1000200
0x1000200

BBB:
4
1 X   因为data的偏移地址要能被2整除  //这应该是4吧??
2
1 XXX 后面那个数组大小超过4字节了,所以根据对齐为4,这里只填充3
10 XX    整体大小对齐到12

于是sizeof(BBB) = 24

p + 0x200 = p本身的值 + sizeof(BBB) * 0x200 = 0x1003000
(结果类型是BBB*)
(Ulong)p+0x200 = 0x1000200.这是整数加法
(结果类型是Ulong)
(char*)p+0x200 = p本身的值 + sizeof(c) * 0x200 = 0x1000200
(结果类型是char*)

///////////

在对齐为4的情况下 
struct BBB
{
long num;  4
char *name; 4
short int data; 2
char ha;;  1+1
short ba[5]; 2*5
}*p;


sizeof(BBB) = 22+2= 24//4的整数倍
p=0x1000000;
p+0x200=____;    
(Ulong)p+0x200=____;
(char*)p+0x200=____;

#19


引用 12 楼 baihacker 的回复:
p+0x200,就是p偏移sizeof(p)*0x200. 
你又写错了 
p+0x200,就是p偏移sizeof(*p)*0x200. 



一个笔试题目
经常笔误的。。
急性子的人,没办法。飞雪那个又字,我好伤心啊。

应该是你又*n写错了。。
一个笔试题目

#20


引用 1 楼 sayigood 的回复:
更正: 

C/C++ code
struct BBB
{
long num;
char *name;
short int data;
char ha;;
short ba[5];
}*p;
p=0x1000000;
p+0x200=_ 0x1000000+0x200*sizeof(BBB)___;
(Ulong)p+0x200=__0x100000+0x200;
(char*)p+0x200=__0x100000+0x200*sizeof(char)__;

#21


唉……

#22


我觉得你可以自己学习一个内存对齐那一块,然后算出结果让大家来讨论……比这样说着强。

楼上已经有解释得明明白白的了。

#23


引用 6 楼 baihacker 的回复:
C/C++ code在数值上分别是:
0x1003000
0x1000200
0x1000200

BBB:
4
1 X   因为data的偏移地址要能被2整除
2
1 XXX 后面那个数组大小超过4字节了,所以根据对齐为4,这里只填充3
10 XX    整体大小对齐到12

于是sizeof(BBB) = 24

p + 0x200 = p本身的值 + sizeof(BBB) * 0x200 = 0x1003000
(结果类型是BBB*)
(Ulong)p+0x200 = 0x1000200.这是整数加法
(结果类型是Ulong)
(char*)p+0x200 = p本身的值 + sizeof(…

sizeof(BBB)=24是对的,但上面的BBB大小的分析过程(红色部分),兄弟看得不是很明白,我是这么理解的:

struct BBB
{
   long num;                  // 4bytes
   char *name;               // 4bytes (在32bit操作系统上,指针是4bytes的)
   short int data;           // 2bytes
   char ha;                  // 1byte
   short ba[5];              // 5 * 2 = 10 bytes
}*p;

因此加起来应该是21bytes,考虑到内存对齐的因素,调整为24bytes。

关于内存对齐的详细解释,请见: 关于内存对齐问题

#24


这个问题的关键还是内存对齐问题, 关于内存对齐问题这篇文章给出了详细的解释,文中是以class来解释内存对齐问题的,同样也适用与struct。

#25


引用 6 楼 baihacker 的回复:
C/C++ code在数值上分别是:0x10030000x10002000x1000200BBB:41X   因为data的偏移地址要能被2整除21XXX 后面那个数组大小超过4字节了,所以根据对齐为4,这里只填充310XX    整体大小对齐到12

于是sizeof(BBB)=24p+0x200=p本身的值+sizeof(BBB)*0x200=0x1003000(结果类型是BBB*)
(Ulong)p+0x200=0x1000200.这是整数加法
(结果类型是Ulong)
(char*)p+0x200=p本身的值+sizeof(c)*0x200=0x1000200(结果类型是char*)


飞雪你这块儿对struct BBB的计算好像有问题!
我觉得应该是这样的:
(4) + (4)+ (2+<补2>)+(1+<补3>)+(5+<补3>) 
我不晓得你的24是怎么算出来的,结果到真是24!

另外还有你的这里:
(Ulong)p+0x200 = 0x1000200.这是整数加法
(结果类型是Ulong)
我觉得(Ulong)类型的大小应该是4,所以(Ulong)p+0x200 = p本身的值+sizeof(Ulong)*0x200

请飞雪和其他看官明鉴!

#26



汗!
陷阱,粗心了,25楼我的回复中,没有看清楚
(Ulong)p+0x200
不是:
(Ulong*)p+0x200
对不起各位啦!

#27


25楼的short为1byte么?这个不对。sizeof(short)=2bytes的。

请再参考: 再谈内存对齐问题

#28


再指出25楼的问题,内存对齐根本不是你那样算的,如果按照你的算法,下面结构(增加了char hb)的大小应该是28了,而事实上仍然是24bytes。

struct BBB
{
long num;
char *name;
short int data;
char ha;
char hb;
short ba[5];
}*p;


所谓内存对齐看的是整个对象是否内存对齐,而不是看对象中某个具体的成员是否内存对齐。

#29


引用 27 楼 pathuang68 的回复:
25楼的short为1byte么?这个不对。sizeof(short)=2bytes的。

请再参考:再谈内存对齐问题

再汗!pathuang68说的一针见血啊!搞得我大热天,虽有开空调,还直冒汗!

(4)+(4)+(2)+(1+<补1>)+(10)+<补2>

飞雪兄,对不住啦!

#30


引用 29 楼 insulted 的回复:
引用 27 楼 pathuang68 的回复:
25楼的short为1byte么?这个不对。sizeof(short)=2bytes的。 

请再参考:再谈内存对齐问题 
 
再汗!pathuang68说的一针见血啊!搞得我大热天,虽有开空调,还直冒汗! 

(4)+(4)+(2)+(1+ <补1>)+(10)+ <补2> 

飞雪兄,对不住啦!

偶尔言中罢了。
哥们,你咋还那样去补齐呀,看看28楼的红色字体部分。

#31


呵呵 内存对齐的问题 还考了几个加法 一个笔试题目

#32


主要还是结构体内存对齐与指针相加问题
http://www.cppblog.com/iuranus/archive/2009/01/06/71388.html

#33


引用 27 楼 pathuang68 的回复:
25楼的short为1byte么?这个不对。sizeof(short)=2bytes的。 

请再参考:再谈内存对齐问题


顶玄机逸士的贴子!

#34


引用 28 楼 pathuang68 的回复:
再指出25楼的问题,内存对齐根本不是你那样算的,如果按照你的算法,下面结构(增加了char hb)的大小应该是28了,而事实上仍然是24bytes。 

C/C++ code
    struct BBB
    {
        long num;
        char *name;
        short int data;
        char ha;
        char hb;
        short ba[5];
    }*p;




所谓内存对齐看的是整个对象是否内存对齐,而不是看对象中某个具体的成员是否内存对齐。

那么这个呢?
struct BBB{
   char ha;
   char *name;
   char hb;
};

#35


引用 30 楼 pathuang68 的回复:
引用 29 楼 insulted 的回复:
引用 27 楼 pathuang68 的回复: 
25楼的short为1byte么?这个不对。sizeof(short)=2bytes的。 

请再参考:再谈内存对齐问题 

再汗!pathuang68说的一针见血啊!搞得我大热天,虽有开空调,还直冒汗! 

(4)+(4)+(2)+(1+ <补1>)+(10)+ <补2> 

飞雪兄,对不住啦! 
 
偶尔言中罢了。 
哥们,你咋还那样去补齐呀,看看28楼的红色字体部分。

大意了!insulted兄这样的 (4)+(4)+(2)+(1+ <补1>)+(10)+ <补2> 是正确的,特此致歉!

#36


引用 34 楼 ltc_mouse 的回复:
引用 28 楼 pathuang68 的回复:
再指出25楼的问题,内存对齐根本不是你那样算的,如果按照你的算法,下面结构(增加了char hb)的大小应该是28了,而事实上仍然是24bytes。 
C/C++ code 
    struct BBB 
    { 
        long num; 
        char *name; 
        short int data; 
        char ha; 
        char hb; 
        short ba[5]; 
    }*p; 

所谓内存对齐看的是整个对象是否内存对齐,而不是看对象…

那么这个呢? 
struct BBB{ 
  char ha; 
  char *name; 
  char hb; 
};

写ltc_mouse兄指正,我想我应该要修改“所谓内存对齐看的是整个对象是否内存对齐,而不是看对象中某个具体的成员是否内存对齐。”这种说法,以免误会。

至于你说到的:

struct BBB

  char ha; 
  char *name; 
  char hb; 
};

因为ha和hb不相邻,中间隔着char* name,因此sizeof(BBB) = [1 + (补3)] + 4 + [1 + (补3)] = 12bytes。这样看起来好像是分别补齐了ha和hb到4bytes。

而下面的代码:

struct BBB

  char *name; 
  char ha;
  char hb; 
};

ha和hb相邻,因此sizeof(BBB) = 4 + [2 + (补2)] = 8bytes。
这样看起来并不是分别补齐ha和hb。

基于这样的原因,我使用了“所谓内存对齐看的是整个对象是否内存对齐,而不是看对象中某个具体的成员是否内存对齐。”这样的说法,现在想来确有不妥,但用一句话也不太好表达,准备写一篇博文以正之。

#37


真理越辩越明,诚哉斯言!

#38


大概看了一下。

4楼和6楼已经给出明确的答案了。

就是一个是指针加法,还是数值加法的问题了。

指针加法,加出来的是指针类型的字节长度的整倍数。
数值加法……那就是有多少加多少了!

像楼主问的,为什么(ulong)p + 0x1 不是加一个ulong的大小……

因为,经过ulong后,这已经不再是指针加法,而变成一个数值加法了,就好像问你 1+1等于几,你不可能得出2以外的结果吧。

楼主你要问的是 (ulong*)p + 0x1 的事儿……别混了

完毕。

#39


最后,对齐为 4与结构体内“最长基本数据类型”的长度(为4)不冲突,所以不用考虑这个值。但若结构体内有一个double型成员的话……就要考虑这个 4 了。

具体的类似问题,上网查吧,就查“数据对齐”,有的是文章,随便看一篇就全明白了!

#40


学习中……

#41


学习了~

#42


引用 38 楼 hikaliv 的回复:
大概看了一下。 

4楼和6楼已经给出明确的答案了。 

就是一个是指针加法,还是数值加法的问题了。 

指针加法,加出来的是指针类型的字节长度的整倍数。 
数值加法……那就是有多少加多少了! 

像楼主问的,为什么(ulong)p + 0x1 不是加一个ulong的大小…… 

因为,经过ulong后,这已经不再是指针加法,而变成一个数值加法了,就好像问你 1+1等于几,你不可能得出2以外的结果吧。 

楼主你要问的是 (ulong*)p + …

6楼那个size分析应该是不正确的。

#43


6 楼分析无误。

#44


我来学习的

#45


#46


内存对齐的话,windows的VS等编译器和GCC的规则是不一眼的,GCC下最多是4,且有压缩什么的

#47


http://www.ksarea.com/articles/20071004_sizeof-struct-memory.html

#48


楼上的高手们都说了。大家看看内存布局就知道了(VS2008)

1>class BBB size(24):
1> +---
1> 0 | num
1> 4 | name
1> 8 | data
1>10 | ha
1>   | <alignment member> (size=1)
1>12 | ba
1>   | <alignment member> (size=2)
1> +---

#49


出这道题的人根本就不懂什么是C语言嘛。
大概没用用过64位的鸡鸡。

$ cat fuck.c && touch fuck.c && make fuck && ./fuck && uname -a
#include <stdio.h>

struct BBB
{
        long num;
        char *name;
        short int data;
        char ha;
        short ba[5];
}*p;

int
main(void)
{
        printf("%lu\n", (unsigned long)sizeof(struct BBB));
        return 0;
}
cc -D_REENTRANT  fuck.c -lpthread -o fuck
32
FreeBSD freebsd.unix-center.net 6.2-RELEASE FreeBSD 6.2-RELEASE #0: Fri Jan 12 08:43:30 UTC 2007     root@portnoy.cse.buffalo.edu:/usr/obj/usr/src/sys/SMP  amd64

#50



$ touch love.c && cat love.c with_you.h && (make love ) && ./love && uname -a && file love                         
#include <stdio.h>

#include "with_you.h"

struct BBB
{
        long num;
        char *name;
        short int data;
        char ha;
        short ba[5];
}*p;

int
main(void)
{
        printf("%lu\n", (unsigned long)sizeof(struct BBB));
        return 0;
}
#pragma pack(1)
cc    -o love love.c 
21
SunOS t1000 5.10 Generic_118833-33 sun4v sparc SUNW,Sun-Fire-T1000 Solaris
love:           ELF 32-bit MSB executable SPARC32PLUS Version 1, V8+ Required, dynamically linked, not stripped
$ touch love.c && cat love.c with_you.h && (CFLAGS='-fast -xarch=v9' make love ) && ./love && uname -a && file love
#include <stdio.h>

#include "with_you.h"

struct BBB
{
        long num;
        char *name;
        short int data;
        char ha;
        short ba[5];
}*p;

int
main(void)
{
        printf("%lu\n", (unsigned long)sizeof(struct BBB));
        return 0;
}
#pragma pack(1)
cc -fast -xarch=v9   -o love love.c 
couldn't set locale correctly
29
SunOS t1000 5.10 Generic_118833-33 sun4v sparc SUNW,Sun-Fire-T1000 Solaris
love:           ELF 64-bit MSB executable SPARCV9 Version 1, dynamically linked, not stripped