请教:关于内存对齐问题。请解释以下程序运行结果。

happyflyingbird 2008-10-30 01:58:49
加精
程序1:
#include <iostream>
using namespace std;
class B0 //声明基类B0
{ public: //外部接口
char nV;
char n;
//void fun(){cout<<"Member of B0"<<endl;}
};
class B1: virtual public B0 //B0为虚基类,派生B1类
{ public: //新增外部接口
int nV1;
};
class B2: virtual public B0 //B0为虚基类,派生B2类
{ public: //新增外部接口
int nV2;
};

class D1: public B1, public B2 //派生类D1声明
{
public: //新增外部接口
int nVd;
//void fund(){cout<<"Member of D1"<<endl;}
};
void main() //程序主函数
{
B0 b0;
B1 b1;
B2 b2;

D1 d1; //声明D1类对象d1
d1.nV=2; //使用最远基类成员
//d1.fun();
cout<<sizeof(B0)<<" "<<sizeof(B1)<<" "<<sizeof(B2)<<" "<<sizeof(D1)<<endl;
cout<<sizeof(b0)<<" "<<sizeof(b1)<<" "<<sizeof(b2)<<" "<<sizeof(d1);



运行结果:
2 10 10 22
2 10 10 22

程序2:
#include <iostream>
using namespace std;
class X1
{
int i;//4个字节
char c1;//1个字节
char c2;//1个字节
};

class X2
{
char c1;//1个字节
int i;//4个字节
char c2;//1个字节
};

class X3
{
char c1;//1个字节
char c2;//1个字节
int i;//4个字节
};
int main()
{
cout<<"long "<<sizeof(long)<<"\n";
cout<<"float "<<sizeof(float)<<"\n";
cout<<"int "<<sizeof(int)<<"\n";
cout<<"char "<<sizeof(char)<<"\n";

X1 x1;
X2 x2;
X3 x3;
cout<<"x1 的大小 "<<sizeof(x1)<<"\n";
cout<<"x2 的大小 "<<sizeof(x2)<<"\n";
cout<<"x3 的大小 "<<sizeof(x3)<<"\n";
return 0;
}

运行结果:
long 4
float 4
int 4
char 1
x1 的大小 8
x2 的大小 12
x3 的大小 8

在visual c++6.0中运行。
对于程序1,由于使用virtual继承,会增加“内部调整指针”,以免使子类重复拷贝同一个数据。由此B0:2个char,2个字节;B1:BO继承来的的2个char+内部调整指针(4字节)+自身int nV1(4字节)=10字节;同理B2也是10字节;D1:从B1和B2那里来的两个“内部调整指针”(8字节)+nV1(4字节)+nV2(4字节)+nVd(4字节)=20字节,其中函数由于存放在代码区,不参与类的sizeof计算。由此好像根本没有考虑内存对齐的问题。

对于程序2,显示考虑了内存对齐。而且好像是4字节对齐。
但是我在project->setting->c/c++->category/code generation->structure member alignment 里,无论怎么设置,结果都一样。

不知道我上面的分析有没有错。
到底什么时候对齐,什么时候不对齐,具体对齐是怎么个对齐法呢?迷惑中。。。。
欢迎大家发表意见。希望了解的高手们能够抽出点点时间帮我解除疑惑,感激不尽!

...全文
2422 57 打赏 收藏 转发到动态 举报
写回复
用AI写文章
57 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2011-11-24
  • 打赏
  • 举报
回复
mark,学习
star143133 2011-10-09
  • 打赏
  • 举报
回复
学习了
tektekman 2011-04-10
  • 打赏
  • 举报
回复
能读懂深入理解计算机系统这些就有不是问题了。
sunbellar 2010-11-01
  • 打赏
  • 举报
回复
刚刚碰到类似问题,呵呵呵
jameslau6 2010-10-22
  • 打赏
  • 举报
回复
好帖子
lumeng394356779 2009-09-24
  • 打赏
  • 举报
回复
菜鸟,在学习中

建立一个群,欢迎高手、菜鸟,一起来学习,一起讨论,一起进步

群号:85864592

新群,人员还不多
lvxiaoqqq 2009-09-24
  • 打赏
  • 举报
回复
学习呵呵
andylhq 2009-09-24
  • 打赏
  • 举报
回复
mark
yaogip 2009-08-26
  • 打赏
  • 举报
回复
mark
happyflyingbird 2008-11-06
  • 打赏
  • 举报
回复
谢谢大家,结贴了!给的分分不好,也不多,希望大家别介意。
SearchLife 2008-11-04
  • 打赏
  • 举报
回复
学习
jeff_nie 2008-11-03
  • 打赏
  • 举报
回复
mark.
sduzhou 2008-11-03
  • 打赏
  • 举报
回复
学习
caitian6 2008-11-03
  • 打赏
  • 举报
回复
学习
oldnwind 2008-11-03
  • 打赏
  • 举报
回复
mark
insulted 2008-11-02
  • 打赏
  • 举报
回复
但是在gcc下编译运行的结果却是:
8
16 32 24 40
16 32 24 40
0022FF40 0022FF44 0022FF48 0022FF50 0022FF58
0022FEF0 0022FEF4 0022FEF8 0022FF00 0022FF04 0022FF08 0022FF10

也就是可以这样推测:
vtrp(4)+ i(1)+ 填充(3)+ nv1(4)+ 填充(4)+ nv2(4)+ nvd(4)+ nv(1)+ 填充(7)+ n(8)= 40

也就是说,在gcc中,只有一个vtrp在最开头占了4个字节
insulted 2008-11-02
  • 打赏
  • 举报
回复
18楼的很好,就是好像D1:nvd 和 B0 的顺序错了。
应该改为:

对于D1:

+--------+----------+
| VB10 | B1:i |
+--------+----------+
| B1:nv1 |
+-------------------+
| VB20 | B2:nv2 |
+--------+----------+
| D1:nvd |
+-------------------+
| B0:nv |
+-------------------+
| B0:n |
+-------------------+

每一行是8字节的,因为最大的是double,八字节!

6*8 = 48
|
|
wzyzb 2008-11-02
  • 打赏
  • 举报
回复
mark
  • 打赏
  • 举报
回复
我想知道这是物理内存还是c语言中的内存
MilanSpiRiT 2008-11-01
  • 打赏
  • 举报
回复
程序1:
b0:| char1 | char1 | == 2

b1,b2:| vptr4 | int4 | char1 | char1 | = 10

d1:| vptr(b1)4 | int(b1)4 | vptr(b2)4 | int(b2)4 | int4 | char1 | char1 | = 22

最后的两个char型,编译器是不给予补齐的

程序2:
x1:| int4 | char1 | char1 | 补2 | = 8

x2:| char1 | 对齐3 | int4 | char1 | 补3 | = 12

x3:| char1 | char2 | 对齐2 | int4 | = 8

程序1改:
b0:| char1 | 对齐7 | double8 | = 16

b1:| vptr4 | char1 | 对齐3 | int4 | 对齐4 | (b0)16 = 32 //最后的B0是8字节一块的,所以B0的首地址要对齐到8字节的边缘

b2:| vptr4 | int4 | (b0)16 | = 24 //先前的4+4=8已经让B0首地址对齐到8字节边缘了,所以不用添加对齐字节

d1:| (b1)32-(b0)16 = 16 | (b2)24-(b0)16 = 8 | int4 | 对齐4 | (b0)16 = 48 //前两部分是b1和b2扣掉各自后面的b0,然后跟上d1自己的数

据,这样总共是16+8+4=28,不在8的整数倍,所以补4,等于32,再把b0放上,就是48
加载更多回复(37)

64,701

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧