我需要删除静态的std :: map吗?

3

在一些类中,我有一个带有指针的静态std::map。我的问题是,我是否需要在程序结束时删除它,还是这个内存会自动释放。我的担忧是,当std::map被删除时,里面存储的指针是否会通过我们的析构函数正确地被删除。

谢谢。

7个回答

6
如果地图包含使用new(或new[]malloc)分配的指针,则每个指针都需要对应的delete(或 delete [],或 free)。
地图的析构函数无法处理裸指针。考虑使用具有适当移动语义的智能指针,例如boost智能指针或者如果您拥有非常新的编译器,则使用C++0x智能指针之一。但是,请不要在STL容器内使用当前标准的std::auto_ptr请参见此线程以了解原因

编辑:

正如Billy ONeal所指出的那样,boost::ptr_map也是专门为此目的设计的。


1
+1 -- 但是关于auto_ptr,我会使用比“避免”更强烈的语言,因为auto_ptr的容器不应该编译。(而auto_ptr在其他地方完全可以使用)还要考虑boost::ptr_map。 - Billy ONeal
谢谢帮助。我认为我需要升级到Boost 1.45。 - Killrazor

2
如果我理解正确,您不会删除地图本身。但是您可能需要删除地图指向的对象。在您的地图中使用智能指针(例如Boost shared_ptr)可能是一个非常好的主意。然后对象将自动清除。
编辑: 使用Boost ptr_map可能是一个更好的主意。

1

内存是“自动释放”的,意思是整个进程的内存被释放,但指向的对象的析构函数不会被调用。如果使用RAII,这可能会导致资源泄漏。


并非总是正确的(尽管对大多数平台来说确实如此) - Billy ONeal

1

std::map 永远不会在其成员上调用 delete。假设您正在使用相对较新的操作系统,操作系统将在进程终止时回收成员占用的内存,但析构函数不会运行。


0
如果您有一个指针映射表,那么答案是“否”,您的析构函数不会被调用,但是“是”,内存将在进程执行结束时被释放。进程分配的所有内存都将在进程退出时(即使它崩溃)由操作系统释放,但析构函数可能不会被调用。

再次强调,这并非总是正确的,但对于大多数平台而言是正确的。 - Billy ONeal

0

内存泄漏是指在一段时间内意外未删除内存,随着进程的继续运行而逐渐减少。如果是长时间运行的进程类型,例如很少重启的服务器,这可能是一个严重的问题。

内存泄漏检测器将捕获任何由编程调用分配但未删除的内存,因此valgrind等工具将报告此类泄漏。

最好使用像valgrind这样的程序来检查您的代码,因此越少的“干扰”,就越容易发现真正的泄漏。因此,我的建议是不要让系统清理内存或单例等,而是自己使用new(或malloc或new[])分配指针。

您可以编写“清理”程序来完成此操作。只需在映射范围内拥有一个对象,该对象具有删除器(因为它将在退出时被删除),该删除器将清除映射中的指针。由于您需要首先删除对象,因此它应该比映射声明晚。


你假设底层平台支持“进程”的概念,但这并不总是正确的。 - Billy ONeal

-1

像任何存储指针的存储类一样:您有责任释放它们所指向的内存。存储类仅负责清理自己的资源。依赖进程终止时由操作系统回收内存是一种不良实践。


一个“存储类”可以做几乎任何事情。现在标准容器不会“删除”任何东西,但完全可以有一个容器,它会摧毁自己的成员。例如,boost::ptr_map/boost::ptr_vector。 - Billy ONeal
@Billy:我不确定Boost容器是否可以视为STL的一部分。它们是基于STL构建的。当前的C++标准不知道Boost,但知道STL(当然,这将随着新的C++0x而改变)。 - Bojan Komazec
@Bojan: 标准规定了STL容器的要求,详见23.2.1。所有boost指针容器库都满足那里列出的要求。它们不在标准库中普通的STL发行版中,但这并不意味着它们不是STL容器。 - Billy ONeal
@Billy 我必须承认我错了,当我说“标准知道STL”时,因为“标准模板库”在ISO/IEC 14882:2003中没有以这个名称提到。基本上,我们有两件事情:(1)C++标准的一部分 - ISO/IEC 14882:2003对“容器库”,“迭代器库”,“算法库”和函数对象的要求集合;(2)STL - 实现这些要求的库(http://en.wikipedia.org/wiki/Standard_Template_Library)。你可能误解了我的意思,当我说“STL容器”时,我想到的是标准容器-... - Bojan Komazec
.../continued/ 这些都是当前标准库的一部分(它们在这篇维基百科文章中列出;ptr_vector 当然不在其中,但 vector 是)。如果您考虑到任何实现标准要求的容器(如 boost::ptr_vector),STL 将通过新的 Boost 容器进行扩展(可能在命名空间 std 中,因此我们将拥有 std::ptr_vector)在 C++0x 中。只有在那时,ptr_vector 才能被视为 STL 容器。如果我漏掉了什么,请纠正我。我们都在学习 :) - Bojan Komazec
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接