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

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

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

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

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

调用fork() ,会创建调用进程的副本。 这个子进程(几乎)与父进程完全相同,即malloc()分配的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()之前分配的malloc()

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

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

整个堆 – 分配的内存以及malloc用于管理它的所有逻辑 – 都是被替换的过程映像的一部分。 就你的过程而言,它就会消失。 当然,该系统可以恢复并回收它。