程序员需要在退出时处理内存释放吗?

3

我有一个程序,当我从键盘输入错误的数据时,它会使用 exit(1) 退出。

我正在使用 Valgrind 进行测试,尽管这种情况下没有错误,但我可以看到仍然存在可达的 x 字节。

所以我的问题是:在触发 exit() 之前,程序员是否需要释放内存,还是操作系统会自动处理?


我认为你正在担心一些现代操作系统已经处理好的事情。例如,在Windows中,你不需要显式地清理GUI - 应用程序的内部结构和操作系统会自动处理它。 - user195488
4个回答

3

这是一个不错的想法(在旧版本的Windows中甚至是必要的),但在现代操作系统上,当程序使用exit()退出时,其整个地址空间将被回收。


3
唯一的例外是System V / POSIX IPC共享内存,除非它的键值为IPC_PRIVATE - geekosaur
1
通常,在退出时释放内存在任何由Valgrind支持的平台上都是完全浪费时间和不好的想法(TM)。对于多线程程序,它还可能引入难以捕获的错误(除非先加入其他线程)。 - Employed Russian

3
最终,操作系统会处理这个问题(在现代的操作系统上是这样的,但在早期版本的Windows上并不是这样)。程序使用的每个资源(内存、打开的文件描述符等)将在程序结束时由操作系统回收(除了一些被设计为在进程终止后仍然存在的资源,主要是某些类型的共享内存/互斥)。
然而,valgrind可以帮助您跟踪内存泄漏,并报告每个可用的内存区域,以便您可以手动释放它们(如果需要的话)。

但在这种情况下,“可达字节”是否意味着存在泄漏?据我所知,即使没有口头报告,该内存部分也可以被读取,因此存在泄漏。 - Pithikos
从应用程序的角度来看,是的,存在内存泄漏,因为应用程序没有“显式地”将内存返回给操作系统。从操作系统的角度来看,不存在内存泄漏,因为它会回收所有内存,无论是否调用了“free”。 - Sylvain Defresne

2

假设我们谈论的是用户空间,我认为通常可以安全地假设在exit()退出时保留内存不是错误。然而,在正常执行期间到达程序结尾且不在exit()中进行解除分配的程序设计是不好的。


0

在退出程序之前释放内存是一个不好的主意。这样做没有任何好处,只会浪费时间,在多线程程序中,如果其他线程没有被加入并且可能访问一些已分配的内存,它实际上可能会导致错误。

"仍然可达"并不是泄漏。请考虑:

#include <stdlib.h>
void *a_global;
int main() {
  void *a_local = malloc(10);
  a_global = malloc(20);
}

gcc -g t.c && valgrind ./a.out

==12228== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==12228== Using Valgrind-3.7.0.SVN and LibVEX; rerun with -h for copyright info
==12228== Command: ./a.out
==12228== 
==12228== 
==12228== HEAP SUMMARY:
==12228==     in use at exit: 30 bytes in 2 blocks
==12228==   total heap usage: 2 allocs, 0 frees, 30 bytes allocated
==12228== 
==12228== LEAK SUMMARY:
==12228==    definitely lost: 10 bytes in 1 blocks
==12228==    indirectly lost: 0 bytes in 0 blocks
==12228==      possibly lost: 0 bytes in 0 blocks
==12228==    still reachable: 20 bytes in 1 blocks
==12228==         suppressed: 0 bytes in 0 blocks

在这里,当你到达退出点时,a_local已经超出了作用域。没有任何方法可以释放该内存;它永远丢失了。这就是泄漏。

另一方面,你可以轻松地释放a_global(虽然你不应该这样做),它是可访问的,并且不是泄漏。


等等,那么你应该显式释放 a_local 吗? - Lawrence Velázquez

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