堆破坏类和全局变量

时间:2016-06-27 15:41:41

标签: c++ destructor heap-memory stdmap

当程序结束时,堆中的项目是否按订单销毁?

以下情况的结果可能是什么:

  1. 创建班级a1, class a1包含static std :: map
  2. 创建类b1,b1析构函数打印地图内容
  3. 将数据插入地图

    std::string mapkey = "abcd";
    map.insert(make_pair(mapkey,20));
    
  4. 退出计划

  5. 如果类b1析构函数打印了' mapkey'的值,是否可能在类b之前销毁映射键字符串,因为它是在类b1之后创建的?因此导致核心转储(因为' \ 0'将不在数组的末尾)?

2 个答案:

答案 0 :(得分:1)

标准说:

  

3.7.3

     

动态存储时长[basic.stc.dynamic]

     
    

1在程序执行期间可以动态创建对象(1.9),     使用newexpressions(5.3.4),并使用deleteexpressions销毁     (5.3.5)。

  

这意味着,在程序结束时,任何分配有new的对象,您的程序尚未与delete一起发布的对象仍将是现存的,并且不会企图销毁它或其成员做成。该对象及其所有成员将被“泄露”。一旦进程结束,大多数操作系统将简单地回收丢失的内存,但同样,它们不会c ++ - 破坏那里表示的对象。

示例:

#include <map>

struct A {
    std::map<int, int> m;
    int i;
};

int main() {
    A a1;  // cleaned up on scope exit
    A* a2 = new A;  // pointer lost on scope exit -- leak
}

因为我们没有delete a2,所以类及其任何成员都没有被销毁,所以a2及其成员使用的所有内存仍然会被分配,直到操作系统回收进程内存为止。

您可以利用RAII来管理这一点,实际上C ++ 11及更高版本提供了“智能指针”来处理这个问题。基本上,智能指针是指针周围的对象包装器;当对象超出范围时,它被破坏,[default]析构函数释放指针:

#include <map>
#include <memory>

struct A {
    std::map<int, int> m;
    int i;
};

int main() {
    A a1;  // concreate instance: destructed on scope exit
    std::unique_ptr<A> a2 = std::make_unique<A>();
    // a2 is a concrete instance of a unique_ptr, so is destructed on scope exit
    // and it's destructor will delete the object pointed to for us.
}

unique_ptr具有非常小的开销,它们几乎只是一个带有包装器的指针,它知道何时超出范围需要为它调用它的对象的析构函数。

在上面的示例中,我们可以将unique_ptr的定义缩短为:

    auto a2 = std::make_unique<A>();

答案 1 :(得分:0)

  

当程序结束时,堆中的项目是否按订单销毁?

没有。当程序结束时,不会销毁具有动态存储的对象(即存储在堆上的对象&#34;#34;)。在指向对象的指针上调用delete时,它们将被销毁。这是在程序结束之前发生的,除非指针泄露。如果指针泄漏,则该对象根本不会被销毁。