返回信息流看了apue,书上说,fork之后,子进程是父进程的复制品,可以获得父进程的资源副本(数据空间、堆和栈的拷贝)。 这里有个疑问,如果我在父进程一开始的地方分配了一个堆内存,那么fork之后,父子进程就会各自有一块堆内存。然后我在子进程中exec一个程序,那么子进程从父进程那里拷贝的那份堆内存算不算是内存泄露了?? 代码如下:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int glob=6;
int main()
{
int* var = (int *)malloc(sizeof(int));
pid_t pid;
*var = 88;
printf("before fork\n");
if((pid = fork())< 0) {
printf("fork error\n");
}else if(pid == 0) { //child process
glob++;
(*var)++;
printf("pid=%d, glob=%d, var=%d, child var address:%0x\n", getpid(), glob, *var, var);
/* 这部分需不需要?如果不需要,是不是在execl的时候 出现内存泄露阿??
if(var != NULL) {
free(var);
var = NULL;
}*/
execl("/bin/sh", "sh", "-c", "ps -elf", (char *)0);
}else{ // parent process
sleep(2);
printf("pid=%d, glob=%d, var=%d, parent var address:%0x\n", getpid(), glob, *var, var);
if(var != NULL) {
free(var);
var = NULL;
}
}
return 0;
}
结果:
before fork
pid=11590, glob=7, var=89, child var address:3400010
中间一堆ps -elf的输出
pid=11589, glob=6, var=88, parent var address:3400010
不理解的地方:
1。这里的var指向的堆的所存内容不同(一个88,一个89),说明堆是各自有一份的,然而 var指针的内容却是相同的。不解??
2。在子进程中难道不需要free(var)吗??
这是一条镜像帖。来源:北邮人论坛 / cpp / #32225同步于 2009/11/27
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
[求助]关于多进程fork以及exec的堆栈问题
p2p
2009/11/27镜像同步30 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
【 在 p2p 的大作中提到: 】
: 看了apue,书上说,fork之后,子进程是父进程的复制品,可以获得父进程的资源副本(数据空间、堆和栈的拷贝)。 这里有个疑问,如果我在父进程一开始的地方分配了一个堆内存,那么fork之后,父子进程就会各自有一块堆内存。然后我在子进程中exec一个程序,那么子进程从父进程那里拷贝的那份堆内存算不算是内存泄露了?? 代码如下:
: #include <stdio.h>
: #include <unistd.h>
: ...................
copy on write
首先,先谢谢你回答哈~~ 是有这个技术阿,cow技术说“ 如果父子进程中任一格式图修改这些区域, 则内核只为修改区域的那块内存做一个副本。”
根据这句话,我在代码中对堆栈内容进行了修改(自增1),所以内核应该为堆开一个副本的。。
【 在 jmpesp 的大作中提到: 】
: copy on write
【 在 p2p 的大作中提到: 】
: 首先,先谢谢你回答哈~~ 是有这个技术阿,cow技术说“ 如果父子进程中任一格式图修改这些区域, 则内核只为修改区域的那块内存做一个副本。”
: 根据这句话,我在代码中对堆栈内容进行了修改(自增1),所以内核应该为堆开一个副本的。。
你再理解下 虚拟地址 跟 MMU 的关系,就应该略知一二了
哦,这样啊,看样子是要看内存管理的部分了。。。能再问一下原文中第2个问题,就是我在execl新程序之后,在子进程中不需要free(var)吗,是不是那个新程序覆盖了子进程的所有空间?
内存这东东太神秘了。。。。。
【 在 jmpesp 的大作中提到: 】
: 你再理解下 虚拟地址 跟 MMU 的关系,就应该略知一二了
【 在 p2p 的大作中提到: 】
: 哦,这样啊,看样子是要看内存管理的部分了。。。能再问一下原文中第2个问题,就是我在execl新程序之后,在子进程中不需要free(var)吗,是不是那个新程序覆盖了子进程的所有空间?
: 内存这东东太神秘了。。。。。
个人以为是需要free的,不要相应的空间就浪费了
【 在 jmpesp 的大作中提到: 】
: 如何理解?
: 别逼着我去翻linux内核代码……
你自己都说了是copy-on-write, 子进程里没有修改var, 那么引用计数是1, 只需要在父进程里free一次就行了
【 在 jokerlee 的大作中提到: 】
: 你自己都说了是copy-on-write, 子进程里没有修改var, 那么引用计数是1, 只需要在父进程里free一次就行了
子进程里已经修改了 (*var)++;
所以需要free