2017-05-19 123 views
0
class Foo{ 
public: 
    Foo(){ 
     cout <<"C "; 
    } 
    ~Foo(){ 
     cout <<"D "; 
    } 
}; 

void func(){ 
    Foo* p = new Foo; 
    p = NULL; 
} 

int main(){ 
    Foo a; 
    for (int i=0; i<1; i++){ 
     Foo b; 
     if (true){ 
      Foo c; 
     } 
     func(); 
    } 
    return 0; 
} 

对于这个问题,输出CCCDCDD,如果我删除FUNC()的主要功能,输出成为CCCDDD,据我所知,前3个C,其中它来自何方,但我不明白剩下的,请解释一下,谢谢。构造函数和析构函数是如何工作的?

+0

'for(int i = 0; i <1; i ++)'本质上执行它的块一次,'if(true)'也一样。如果你想定义一个范围,你可以简单地使用一对大括号('{}')。您不需要在流控制语句的上下文中使用它们,您可以简单地执行'int main(){Foo a; {Foo b; {Foo c; } func(); } return 0; }' –

+2

通过调试器逐步完成此操作可能会有所帮助...... – Borgleader

+0

'p = NULL;'实际上并不会销毁对象。新的Foo对象被泄露。这行应该读取'delete p;'。 – cdhowie

回答

2
  1. Ç - 一个被构造
  2. Ç - B被构造
  3. Ç - c的构造
  4. d - 一个对象foo是动态 - becouse离开范围
  5. C C被desctructed分配并指向p,但由于它是动态分配的,并且从不删除,所以它永远不会被破坏。
  6. d - B被破坏
  7. d - 一个被破坏
1

有顺序将是CCCDCDD:

  1. Ç - 建筑甲
  2. Ç - 构建体B
  3. Ç - 构建体C
  4. D - 破坏C
  5. ℃ - 建筑P(在FUNC)
  6. d - 自毁乙
  7. d - 自毁甲

// memleak对于p(在FUNC)

0

当包括func();呼叫,则采取的措施有:

Foo a; -> C 

Foo b; -> C 

Foo c; -> C 

Left the scope of Foo c -> D 

func(); call -> 
    new Foo; -> C 

Finished func() call, left the scope of Foo b -> D 

Left the scope of Foo a -> D 

注意,在FUNC()创建的Foo对象是永远不会解体,这意味着你有内存泄漏。

1

对象a的范围是函数main的外部代码块的范围。它是第一个创建的对象和最后一个被删除的对象。

int main(){ 
    Foo a; 
    // ... 
    return 0; 
} 

C C C D C D D 
|   | 
a   a 

然后,在for循环仅具有一个迭代那里被创建在如果

语句的块范围的循环的第一次迭代之后删除

for (int i=0; i<1; i++){ 
    Foo b; 
    // ... 
} 

C C C D C D D 
| |  | | 
a b  b a 

然后,对象b

if (true){ 
     Foo c; 
    } 

有创建和删除该对象c

C C C D C D D 
| | | | | | 
a b c c b a 

后,该功能func被称为

func(); 

在函数内部有使用new运算符创建了一个未命名的对象,并指向指针p

void func(){ 
    Foo* p = new Foo; 
    p = NULL; 
} 

C C C D C D D 
| | | | | | | 
a b c c p b a 

此对象不会被删除,因为不会为此对象调用操作符delete。所以存在内存泄漏。

就是这样。

相关问题