浪迹天涯

唯有努力...
努力....再努力...

再谈sizeof()的问题

union A
{
int a[5];
char b;
double c;
};

struct B
{
int n;
A a;
char c[10];
}

32位机器环境,求sizeof(B) = ?
先别在机器上跑,大家自己先算算,然后确认看看和你算的是否一致。
然后再讨论讨论,我先前以为对sizeof理解透了,没想到算这个的时候还是没吃透,答案就先不说了,卖个关子!
如果union A改为struct A,结果又如何呢?

posted on 2008-02-29 17:23 浪迹天涯 阅读(3462) 评论(17)  编辑 收藏 引用 所属分类: C++

评论

# re: 再谈sizeof()的问题 2008-02-29 18:20 comiunknown

我在WM5的手机上运行后的结果是48,32位PC机估计结果一样,
sizeof(A) = 24
奇怪48是怎么来的  回复  更多评论   

# re: 再谈sizeof()的问题 2008-02-29 19:55 hg

内存对齐,不同的编译器你规则不同  回复  更多评论   

# re: 再谈sizeof()的问题 2008-02-29 20:06 54sun

这个不是sizeof()的问题吧,应该是struct的问题,其中的变量只能以自己大小整数倍的大小地址开始,所有就算变量相同,但是会因为顺序不同最后struct的大小也会不同。不知道lz是不是想说这个?  回复  更多评论   

# re: 再谈sizeof()的问题[未登录] 2008-02-29 21:39 a

你空间是不是被挂马了?  回复  更多评论   

# re: 再谈sizeof()的问题 2008-02-29 23:57 Fox

int 4
union 20
c 10
34
如果考虑4字节对齐,应该是36  回复  更多评论   

# re: 再谈sizeof()的问题 2008-03-01 08:42 浪迹天涯

我的意思不是说sizeof()函数的问题。
我本意也并不是讨论各个编译器的规则。
我是想探讨sizeof()求结构struct,union时的规则。
很不厚道,有人在机器上跑了一趟,不过依然谢谢。
union A:
{
int a[5]; //20
char b; //1
double c; //8
}我想的是union中变量共用内存,应以最长的为准,那就是20。可实际不然,sizeof(A)=24,后来一想应该是必须考虑A中各变量的默认内存对齐方式,必须以最长的double 8字节对齐,故应该是sizeof(A)=24。
关于sizeof(B)下篇再续,也希望大家多探讨探讨,写下你的想法!  回复  更多评论   

# re: 再谈sizeof()的问题 2008-03-01 08:52 浪迹天涯

没有挂木马,是计数器卡着了@a
  回复  更多评论   

# re: 再谈sizeof()的问题[未登录] 2008-03-01 12:26 CppExplore

空间有毒!!!!大家小心
@浪迹天涯
如果是什么计数器卡着了,也请修改正常。  回复  更多评论   

# re: 再谈sizeof()的问题 2008-03-01 13:20 kimiya25

如果这样写我运行却是40..
struct {
int n;
char c[10];
union {
int a[5];
char b;
double c;
} u_a;
} B;  回复  更多评论   

# re: 再谈sizeof()的问题 2008-03-01 21:43 Fisher

struct B
{
int n; // 4字节
A a; // 24字节
char c[10]; // 10字节
};
实际占用38字节,但由于A是8字节对齐的,所以int n和char c[10]也需要8字节对齐,总共8+24+16=48  回复  更多评论   

# re: 再谈sizeof()的问题 2008-03-02 23:26 sad

挂马了,请清理  回复  更多评论   

# re: 再谈sizeof()的问题 2008-03-03 08:44 浪迹天涯

空间还有毒吗?我什么东西都没放啊!  回复  更多评论   

# re: 再谈sizeof()的问题 2008-03-04 11:12 frank.sunny

非常感谢,说实话,我也不幸中招了

死得很惨,惭愧一下

  回复  更多评论   

# re: 再谈sizeof()的问题 2008-03-04 13:04 李侃

字节对齐问题,可以取消pack(4)到pack(1) ,结果就又不一样了哦  回复  更多评论   

# re: 再谈sizeof()的问题 2008-03-04 16:00 眯着眼的猫

可以这么理解吧:
内存对齐主要目的是提升读取数据的速度,通过保证 类型数据(n字节)保存在n倍数的内存

地址上。(n越大,要求越严格。)
要做到这点,有3个位置要求。
首地址,调到最严格地址倍数上,不影响大小。
中间项,按各自下一项的地址要求填充调整,影响大小。
最后一项,通过填充,达到最严格地址大小倍数,影响大小。
union A
{
int a[5];
char b;
double c;
};
对于union A(共享内存),其实只有一项
至少需要20字节。首地址可以解释为3种类型,
A =a时,
| 4 | 4 | 4 | 4 | 4 | ,20字节
中间和尾部都不需调整。
A =b时,
|1|.................|,
中间和尾部都不需调整,20字节。
A =c时,
| 8 |...........|,
c作为最后项,需要调整20-〉24
因此,内存布局:
| 4 | 4 | 4 | 4 | 4 |...| (...为padding),total=24

struct B
{
int n;
A a;
char c[10];
};
这里要注意a,是作为A类型,是一项数据。
对于 struct B,最严格8字节,
首地址为8的倍数,填入n,(后面空4个字节,因为a的开始地址要求8的倍数)
c,开始地址无特殊要求,a后面无需填充,
作为尾项,c,10-〉16
| 4 |...| 4 | 4 | 4 | 4 | 4 |...|10->16|

to kimiya25:
struct C{
int n;
char c[10];
union {
int a[5];
char b;
double c;
} u_a;
};
n: 4
c: 10->12
u_a: 24
| 4 | 10 |...| 24 |
//----------------------------------
效率的解释:例处理器每次从内存读入8个字节的数据,当我们需要一个double类型的数据

时,通过在写入内存时改保证数据写在8倍数的地址上,就能够只用一次读,否则可能跨越

,需要两次  回复  更多评论   

# re: 再谈sizeof()的问题 2008-03-05 08:30 浪迹天涯

@眯着眼的猫
很感谢眯着眼的猫 解释的很详细!
我先前以为对sizeof()理解的很透彻,但遇到这个union一开始没有理解透彻,直到在机器上跑一遍以后,才理解清楚。  回复  更多评论   

# re: 再谈sizeof()的问题 2008-03-05 10:28 Fox

问题出在union的对齐上面,要按照单位最长的成员对齐。。。。
学习了  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2008年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

导航

统计

常用链接

留言簿(22)

随笔分类(30)

随笔档案(29)

文章分类

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜