局部变量的析构函数是否始终保证在超出范围时被调用?

时间:2013-04-28 17:13:29

标签: c++ memory-management destructor

编译器可以进行很多优化(比如内联一些函数),并且我有点怀疑在我的程序中调用函数后不是所有为局部变量分配的内存都被清除了(基于OS X的系统监视器) ),这就是我要问的原因:标准是否保证局部变量的所有析构函数在它们超出范围时都会被调用?

5 个答案:

答案 0 :(得分:8)

是。根据C ++ 11标准的3.7.3段:

  

显式声明register或未明确声明staticextern的块范围变量具有自动   存储时间这些实体的存储会持续到创建它们的块   退出

但请注意,这涉及具有自动存储持续时间的变量。如果使用new动态创建对象并将结果分配给本地原始指针,则仅销毁原始指针,而不是指向对象:

{
    int* foo = new int(42);
} // Here you have a memory leak: the foo pointer is destroyed,
  // but not the object foo pointed to

答案 1 :(得分:7)

是的,这是有保障的。

使用系统监视器监视内存使用情况可能不准确,因为应用程序不会将内存返回给系统。一旦分配,它就属于应用程序,即使您的对象被销毁,也可能看不出任何差异。

如果您想保证您的应用程序没有内存泄漏,您可能需要使用valgrind或google的drMemory或其他几个工具(google用于“内存泄漏检测”)。在这种情况下,您将获得有关分配,解除分配,泄漏,内存访问违规等的最准确信息。

答案 2 :(得分:3)

是的,保证超出范围的每个变量都会调用它的析构函数。

6.7声明声明

  

2每个声明语句都会初始化具有自动存储持续时间(3.7.3)的变量   执行。 块中声明的具有自动存储持续时间的变量在退出时被销毁   阻止(6.6)。

答案 3 :(得分:1)

如果你有这样的代码:

void f()
{
  A a;  // create a local instance of A
        // memory will be allocated on the stack, 
        // and the constructor for `a` will be called.

  // various code here

  // here at the end of the scope, 
  // the destructor for `a` will be called,
  // and the memory on the stack will be freed.
}

答案 4 :(得分:0)

是的,这将永远发生。它由C ++保证。来自C++ FAQ lite

[11.5]我应该在局部变量上显式调用析构函数吗?

没有!

析构函数将在创建本地的块的close}处再次被调用。这是语言的保证;它自动发生;没有办法阻止它发生。但是你可以通过第二次在同一个对象上调用析构函数来获得非常糟糕的结果!砰!你死了!


它有点超出你的问题,但基数是相同的。