一、解析这一段简单的代码:
class Class
{
public:
char a;
char *b;
Class::Class()
{
a=5; (1)
// * (&a+1)=5; (3)
}
};
int _tmain(int argc, _TCHAR*argv[])
{
Class *p=new Class[2]; (2)
detele[]p;
while(1);
return 0;
}
二、通过代码画出的结构图
三、解析
- (2)中 p(0x800)new出一块连续的空间,分成两份(实际就是一块)0x900和0x905:
- 只有地址名字,没有变量名
- 每份大小是一样,大小根据类里有多少成员属性来计算(例如这里的0x900和0x905的空间大小同是5字节,因为类里一个指针一个char变量)
- 每份都有同样的成员变量
- 在类里给成员变量赋值,会给多个对象的相同成员变量同时赋值((1)里a=5,0x900和0x905都会赋值为5<如图>,
像(3)里找到0x901的地址赋值,会出现0x900是cd,0x905赋值为5,后面空间地址以此类推,如果new Class[4],0x910和0x915仍然被同时赋值5<如图>
,为什么呢,new Class[n]调n次构造)
- 在main里可以给任意对象赋值且其他对象不会赋值
- 这样情况下用detele或detele []效果一样,将开辟的这一块连续的空间都释放
以上属于简单情况
四、复杂情况下代码:(5)代码,成员指针初始化
class Class
{
public:
char a;
char *b; (4)
Class::Class()
{
b=new char; (5)
}
};
int _tmain(int argc, _TCHAR*argv[])
{
Class *p=new Class[2]; (2)
detele[]p;
while(1);
return 0;
}
五、解析复杂代码
- 1. 这样成员指针b,new出来的空间有可能连续
- 2. 同样只有地址名没有变量名
- 3. New出来的每块空间大小一样,大小根据成new的大小
- 4. 类里赋值,都会赋同样的值,main里可以单独赋值
区别在于main里用detele的时候,只会调一次析构函数,这样,0x900 0x905 0x700空间被释放,0x605……内存泄漏,用detele []p,就会调过几次构造就调几次析构,就都会释放
detele和detelp[]区别,detele用于释放new出单个对象的空间
detele[]用于释放new[]出多个对象的空间
六、通过代码画出的结构图
练习:
1.将结构图能画出
2.给其中的0x900、0x905、0x700、0x605单独赋值
解2:
发现:(p + n)->a能直接找到0x900划分的第几份的int a,(p + n)->b能直接找到0x900划分的第几份的char *b,相当于给0x700、0x605单独赋值了