我不明白,为什么指针front指向对象berta(我知道anton和berta是在堆栈上创建的)
1 Hello* front;
2
3 void createHello() {
4 Hello anton("Anton");
5 front = &anton;
6 }
7
8 int main() {
9 createHello();
10 Hello berta("Berta");
11 front->body();
12}
1 class Hello {
2 Hello(const char* name) : name(name) {
3 out.print(name);
4 out.print(" ctor;");
5 }
6
7 ~Hello(){
8 out.print(name);
9 out.print(" dtor;");
10 }
11
12 void body () {
13 out.print(name);
14 out.print( " body;");
15 }
16
17 const char* name;
18};
输出:Anton ctor;Anton dtor;Berta ctor;Berta body;Berta dtor;
out.print() 是一个简单的函数,可以在监视器上打印字符串
我以为会发生这样的事:
createHello() - 寄存器被压入堆栈,返回地址被压入堆栈
Hello anton("Anton") - 对象将被推入堆栈
前面=&安东;指针指向 anton 的地址
esp - 将被设置为函数调用之前的位置
你好,伯塔(“伯塔”); - 对象“berta”将被推入堆栈
前端->body(); - 打印贝尔塔身体;到底为什么会发生这种事?
我的意思是前指针应该指向堆栈中的不同位置:
1.{下地址}
安东<-front <-esp
返回地址
注册
{上级地址}
2.
安东<-front
返回地址
注册
<-esp
3.
安东<-front
返回地址
伯塔<-esp
所以应该只有两种可能性:anton 将被部分覆盖,或者它仍然存在,而 berta 处于更高的存储位置。如果 anton 将被部分覆盖,那么应该会出现一些 Front->body 的 rnd 内容。如果 anton 不会被覆盖,那么它应该返回“Anton body;”。
你能向我解释一下为什么这种情况没有发生吗?相反,berta 会覆盖对象 anton,以便 front 点恰好位于 berta 上?
@编辑忘记了*,所以前面是一个指针
@编辑我永远不会编程某事。以这种方式 - 我的大学给了我这个废话 - 不知道如何解决它 - 是的,我只能说“嗯,berta完全在安东上创建并覆盖了他”,但我不明白为什么 - 通常应该在更高的地址上创建berta .
一旦您对
createHello()
的调用返回,Anton 就会超出范围并调用其析构函数,因此您的输出:
Anton ctor;Anton dtor;
此时,
front
是一个悬空指针。
然后创建 Berta,它被压入堆栈中 Anton 曾经存在的位置,导致
front
指向 Berta。
如果您使用
new
在堆上分配 Anton,Anton 将在程序的整个生命周期中持续存在,或者直到您调用 delete
。
编辑:根据戴尔的评论,这种行为应该被认为是巧合。编写假设 Berta 始终存在于 Anton 所在的同一地址的代码是不明智的。