C++ class实例的内存结构
Author:zfive5(zidong)
Email:zfive5@yahoo.com.cn
引子
这些天让一些概念和算法烦得不知所措,只能听从佛祖教诲的:放下,然后上csdn去,看了两篇关于c++的文章,这个年头,能这样拷问“茴”字多个写法的人不多了,在这里赞一下,但里面的一些东西还是没有挖掘干净,所以有了写一些东西的冲动.
正文
在c++中,一个类虚函数表指针和成员是如何在内存中组织的大家看前面的文章已经很清楚了,但如果出现一堆继承关系后,它们又是怎样在内存结构组织的,这里并不想用汇编语言来说明,而是直接看数据区的内存里的内容来推演出结论。
要实验的类继承结构关系图如下:
其中成员函数都是虚函数,成员变量在构造函数里初始化成如下,便于发现内容边界:
A:
iA1=0xA1A1A1A1;
iA2=0xA2A2A2A2;
B:
iB1=0xB1B1B1B1;
iB2=0xB2B2B2B2;
C:
iC1=0xC1C1C1C1;
iC2=0xC2C2C2C2;
D:
iD1=0xD1D1D1D1;
iD2=0xD2D2D2D2;
E:
iE1=0xE1E1E1E1;
iE2=0xE2E2E2E2;
代码如下:
int _tmain(int argc, _TCHAR* argv[])
{
A *pA=NULL;
B *pB=NULL;
C *pC=NULL;
D *pD=NULL;
E *pE=NULL;
pE= new E();
pA=pE;
pB=pE;
pC=pE;
pD=pE;
return 0;
}
在监视器里看到变量内容如下:
pE
0x003e9e58 {iE1=-505290271 iE2=-488447262 } E *
pB
0x003e9e58 {iE1=-505290271 iE2=-488447262 } B *
pA
0x003e9e64 {iE1=-505290271 iE2=-488447262 } A *
pC
0x003e9e64 {iE1=-505290271 iE2=-488447262 } C *
pD
0x003e9e78 {iE1=-505290271 iE2=-488447262 } D *
综合一下就可以得到这样的内存结构:
如果类里面没有虚函数的话,在上表里就没有对应的那个虚函数表指针。
虚函数表指针指向内存也同样可以看内存得出如下内容:
0x00417640:
03 12 41 00 (HelloB)
6e 10 41 00 (HelloE)
00 00 00 00 (NULL)
0x00417688:
6c 12 41 00 (C的析构函数)
90 11 41 00 (HelloA)
37 10 41 00 ( HelloC)
37 10 41 00 ( HelloC)
00 00 00 00 (NULL)
0x0041767c:
76 12 41 00 (HelloD)
00 00 00 00 (NULL)
以上实验分析是在vc++ 2005环境下进行的,估计vc6.0也是如此的内存分布,但gc++一定有所不同(以前看过一些相关的文章,今天本来想下载一个cygwin0528安装包验证一下,结果g了半天,全都是死连接,等回到北京再去实验一下吧)
向拔掉的第一颗牙,说再见,拔牙的痛苦的耐人寻味!以后一定更加珍惜爱护自己的牙!!!
相关文章