【发布时间】:2011-08-31 08:40:03
【问题描述】:
在此处查看execvp 的 NetBSD 实现:
注意第 130 行的注释,在处理ENOEXEC 的特殊情况下:
/*
* we can't use malloc here because, if we are doing
* vfork+exec, it leaks memory in the parent.
*/
if ((memp = alloca((cnt + 2) * sizeof(*memp))) == NULL)
goto done;
memp[0] = _PATH_BSHELL;
memp[1] = bp;
(void)memcpy(&memp[2], &argv[1], cnt * sizeof(*memp));
(void)execve(_PATH_BSHELL, __UNCONST(memp), environ);
goto done;
我正在尝试将 execvp 的这个实现移植到独立的 C++。 alloca 是非标准的,所以我想避免它。 (其实我想要的函数是来自FreeBSD的execvpe,但这更清楚地说明了问题。)
我想我明白为什么如果使用纯 malloc 会泄漏内存 - 虽然 execvp 的调用者可以在父级中执行代码,但对 execve 的内部调用永远不会返回,因此函数无法释放 @ 987654331@ 指针,并且无法将指针返回给调用者。但是,我想不出替换alloca 的方法——避免这种内存泄漏似乎是必要的魔法。我听说 C99 提供了可变长度的数组,但遗憾的是我不能使用它,因为最终的目标是 C++。
是否可以替换 alloca 的这种用法?如果强制要求保持在 C++/POSIX 中,那么在使用该算法时是否存在不可避免的内存泄漏?
【问题讨论】:
-
你说这是一个独立的C++环境?它是否提供
vfork?如果它不提供vfork,或者如果vfork在这个环境中与fork相同,那么您可以调用malloc或new而不必担心内存泄漏。在forked 孩子中,你所做的任何事情都不会修改父母的记忆。 -
啊!出于某种原因,我假设该评论也适用于 fork() 。由于环境不提供vfork,此题无效!非常感谢。
-
@Rob 我认为只调用 fork 而不是 vfork 是无效的,因为 vfork 的行为与 fork 不同(一个立即返回,另一个仅在新进程调用 exec 或_exit)。