exec()更改程序映像后malloc的内存会发生什么?

时间:2011-03-25 06:08:13

标签: c++ c memory-management exec

我知道当我在Linux中调用其中一个exec()系统调用时,它将使用新映像替换当前正在运行的进程。因此,当我分叉一个新进程并运行exec()时,子进程将替换为新进程。

我从堆中分配的内存会发生什么变化?假设我想解析任意数量的命令并将其发送到exec()。为了保持这个任意数字,我可能不得不在某些时候分配内存,因为我认为我不能正确使用静态大小的数组,所以我可能会使用malloc()或类似的东西。

我需要保留这个内存,直到我调用exec(),但exec()永远不会返回。

操作系统是否回收了内存?

2 个答案:

答案 0 :(得分:25)

当您致电fork()时,会创建一个调用流程的副本。这个子进程(几乎)与父进程完全相同,即malloc()分配的内存被保留,您可以自由地阅读或修改它。但是,父进程不会看到修改,因为父进程和子进程是完全分开的。

当您在孩子中呼叫exec()时,子流程将被新流程替换。来自execve(2):

execve() does not return on success, and the text, data, bss, and stack
of the calling process are overwritten by that of the program loaded.

通过覆盖data段,exec()调用有效地回收了malloc()之前分配的内存。

父进程不受所有这些影响。假设您在调用fork()之前在父进程中分配了内存,则内存在父进程中仍然可用。

编辑:malloc()的现代实现使用匿名内存映射,请参阅mmap(2)。根据execve(2),内存映射不会在exec()调用中保留,因此也会回收此内存。

答案 1 :(得分:4)

整个堆 - 分配内存,以及所有逻辑malloc 用来管理它 - 是过程图像的一部分 更换。就你的过程而言,它就会消失 关心。当然,该系统可以恢复并回收它。