假设函数func有错误,以便泄漏内存。
pid_t childPid;
int status;
childPid = fork();
if (childPid == -1)
errExit("fork");
if (childPid == 0) /* Child calls func() and */
exit(func(arg)); /* uses return value as exit status */
/* Parent waits for child to terminate. It can determine the
result of func() by inspecting 'status'. */
if (wait(&status) == -1)
errExit("wait");
问题1> 如果一个程序泄漏内存,程序最终退出后,它是否仍会泄漏内存或者系统会收集程序分配的所有内存并且没有更多泄漏的内存?
问题2> 在父进程调用wait之后,子进程中func引起的泄漏内存是怎么回事?
答案 0 :(得分:6)
如果一个程序泄漏内存,程序最终退出后就会这样做 仍然泄漏内存或系统将收集所分配的所有内存 程序并没有更多泄露的记忆?
系统将从子进程收集所有内存资源,并且子进程将不再有任何泄漏的内存。此外,对fork()
的调用会分隔父项和子项的内存空间,因此子进程中的泄漏不会在父进程中泄漏,除非您在两者中调用相同的错误函数。
在父进程调用wait之后,泄漏的内存是怎样的 由子进程中的func引起的?
在父母中调用wait()
,并且泄漏内存的孩子实际上彼此没有任何关系。父对wait()
的调用仅导致父进程阻止等待指示子进程已完成的信号。在孩子完成之前,孩子仍然必须先致电func()
,因为它必须将func()
的返回值传递给exit()
。因此,func()
在技术上可以“泄漏”内存,因为它在堆上分配了一些内存,但是没有清理它,即使操作系统的清理操作几乎在{{1}之后立即发生。 } 叫做。换句话说,在调用func()
之后,操作系统已经释放了孩子使用的资源,但是exit()
本身仍然无法释放它试图分配的任何内存。
答案 1 :(得分:3)
任何现代操作系统都不允许子进程(或任何进程)在终止后使系统处于不一致状态。
如果该函数在导致分段错误的意义上是错误的,则操作系统通常会在攻击后立即使用信号SIGSEGV
终止该进程,并且将通过{{1}确认父进程。孩子已经通过信号退出,而不是通常。
答案 2 :(得分:3)
内存泄漏只是一种资源泄漏。
分配的内存页面,例如malloc()被称为“私有页面”,因为它们只属于一个进程(它们可能是与父或子共享的写时复制,但它们仍然是它自己的页面)。
但是,还有很多其他方法可以泄漏资源。某些类型的共享对象不会被自动清理;文件系统中的文件不会被自动清理,子项创建的子进程也不会在退出时自动获取。