在atexit()中释放资源

13

在atexit()函数中释放内存有意义吗?

我有一个全局变量,在启动后进行了malloc分配。我可以编写一个atexit()函数来释放它,但是程序退出时系统不会收回所有那些内存吗?

主动清理自己是否有益处?


听起来像是重复的问题,参见https://dev59.com/cnE95IYBdhLWcg3wp_un。 - unwind
8个回答

22

在C语言中没有这样的操作-这就像是在船下沉时重新排列甲板上的椅子。

而在C++中情况不同,因为对象可以在它们的析构函数中删除临时文件等内容,所以你需要确保这些析构函数被调用。


15

释放它的一个好处是,如果你进行任何内存泄漏测试,试图在进程生命周期内匹配分配和释放,你就不会从这种故意泄漏中得到误报。


Purify曾用于在调用atexit()清理之前进行内存泄漏测试。这很让人烦恼。但那也是十年前的事情 - 自那时以来可能已经有所改变。 - Jonathan Leffler

14

由于malloc()/free()通常涉及存在于用户空间中的大量数据结构,因此在程序结束时free()内存实际上可能会影响性能。如果数据结构的某些部分被分页到磁盘上,则需要从磁盘加载它们,然后才能将其丢弃!

而如果不使用free()终止程序,则分页到磁盘上的数据可以安心地死去。

当然,在其他时间使用free()通常是有益的,因为进一步的malloc()可以重用您释放的空间,free()甚至可以取消映射一些内存,这些内存随后可以被其他进程使用。


13
在所有现代操作系统中,您可以安全地假定当程序退出时所有内存都将被释放。

7
实际上,当你的程序不断发展时,保持整洁会变得更加有趣。这会迫使你在创建“初始化”函数时编写清理功能。好处在于,当你的程序变得更加复杂,并且想要重新启动部分程序时,如果你已经编写了可行的清理函数,那么就不太可能忘记一些清理工作。
只有在需要时才“懒散地”编写清理函数,这样做更容易出错。编写清理函数会迫使你思考清理和可能的清理依赖关系。它允许更容易地在另一个项目中重用代码的一部分。
所以,虽然在atexit中释放和关闭文件描述符都是无用的,但随着代码不断增长编写和维护清理函数可能会成为一种约束,迫使你考虑自己在做什么。

5

如果你的代码调用了atexit(),而且这部分代码是作为动态加载的共享库(例如使用dlopen())的一部分,则应该使用free()。在这种情况下,atexit处理程序将在dlclose()时调用,因此堆将继续存在,以供进程的其余部分使用。


2
在Windows平台上,一些调用会返回属于操作系统或COM的内存,你需要显式地释放该内存,否则即使在进程终止后它也不会被释放。但这是一个罕见的情况。

1

在进程终止之前不释放内存并不是内存泄漏。只有当你失去对它的控制时才会出现内存泄漏。但是内存并不是唯一的资源类型,其他资源会跨进程持久存在(例如窗口句柄和文件句柄),因此您确实需要“释放”这些资源。


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