免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3861 | 回复: 17
打印 上一主题 下一主题

[C] malloc与fork问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-05-29 11:16 |只看该作者 |正序浏览
1.代码
#include <unistd.h>
#include <stdio.h>
#include <errno.h>

main()
{
    char *ptr;
    pid_t child;

    ptr=(char *)malloc(20);

    child=fork() ;
    if ( child<0 ) {
        perror("fork err");
        exit(-1);
    } else if ( child==0 ) {
        sleep(1);
        printf("%d,%p,[%s]\n",getpid(),ptr,ptr);
        exit(0);
    } else {
        strcpy(ptr,"hello");
        printf("%d,%p,[%s]\n",getpid(),ptr,ptr);
        wait(NULL);
        exit(0);
    }
}

执行结果是:
2200,403b44,[hello]
2201,403b44,[]
以前听说子进程如果不改变ptr的值,那么就不重新分配空间,地址是没有变化,可为什么取不到值,是不是403b44是内存相对地址?

2.还想问个问题,一个函数,fork之后子进程malloc,然后exit退出子进程,再return退出函数,之间没有free会不会内存泄露?

论坛徽章:
0
18 [报告]
发表于 2008-05-29 20:47 |只看该作者

回复 #17 augustusqing 的帖子

谢谢,明白了

论坛徽章:
0
17 [报告]
发表于 2008-05-29 20:06 |只看该作者
原帖由 rock_jq 于 2008-5-29 12:03 发表
int function()
{
      child=fork();
      if (child==0) {
            malloc(...);
            execl(...);
      }

      wait(status);
      
      return(status)
}

进程执行exec系列函数后,整个进程的所有资源,如文本段,数据段,栈,堆,就会被新程序的资源替代,原先进程使用malloc在其原来的堆上分配了地址,紧跟执行exec函数,这个堆会被新程序的堆替换。所以那个malloc不会造成什么内存泄露。

因为执行完execl后程序就exit退出了,所以没有free。

你这句话是错误的,执行完execl后,进程就跳转执行execl调用的新程序,在execl后没法执行exit退出的(要说执行exit也是在execl调用的新程序中执行),更不用说什么free了。

论坛徽章:
0
16 [报告]
发表于 2008-05-29 18:55 |只看该作者
你可以使用
1.管道文件
2.共享内存
3.消息队列
4.多线程
来实现对一段内存的共同修改

论坛徽章:
0
15 [报告]
发表于 2008-05-29 18:54 |只看该作者
问题一:我也碰到过,我是设置一段缓存,然后就想利用fork()返回值的不同来区分父子进程,让这两个进程一个往缓存里面写,一个从缓存往外面读。结果就是我在一个进程往里面写了,另一个进程根本看不见修改。
但是,父子进程之间的资源是独立的,如果从OS的角度讲,每次创建一个进程的时候,OS会给这个进程创建一个PCB(
Process Control Block进程控制块,里面存放诸如机器指令,寻址的位置等),而每个进程的PCB都是不同的,因此OS也把
PCB当做是区别不同进程的标准。因为PCB不同,自然无法寻找同一个地址(这里是物理地址)

论坛徽章:
0
14 [报告]
发表于 2008-05-29 14:51 |只看该作者

回复 #10 caijimin 的帖子

我不是偷懒啊,看8楼的说明,我是没法free啊

论坛徽章:
0
13 [报告]
发表于 2008-05-29 14:50 |只看该作者
原帖由 weedeater 于 2008-5-29 14:26 发表
就是说,ptr的值403b44并不是物理地址,这个值在你的程序里不会变。会变的是进程页表中的物理地址。
在改写403b44的内容之前,由于写时复制机制,子进程和父进程的“403b44”共享同一个页,映射的是同一块物理 ...

谢谢,明白。

论坛徽章:
0
12 [报告]
发表于 2008-05-29 14:29 |只看该作者
写时复制
进程退出,内存即释放。

论坛徽章:
0
11 [报告]
发表于 2008-05-29 14:26 |只看该作者
就是说,ptr的值403b44并不是物理地址,这个值在你的程序里不会变。会变的是进程页表中的物理地址。
在改写403b44的内容之前,由于写时复制机制,子进程和父进程的“403b44”共享同一个页,映射的是同一块物理地址。当其中一个进程改写了403b44地址的内容时,这个页就被复制了一份,“403b44”映射到了不同的物理地址上
这个是内核作的工作,对用户透明。

论坛徽章:
0
10 [报告]
发表于 2008-05-29 12:35 |只看该作者
虽然进程退出后OS会自动回收内存,可这不是我们偷懒的接口,
万一谁把那段程序copy到长期运行的服务器程序去呢,
程序退出后打开的文件描述符都会close,
那是否我们就只管open, 不去close呢?
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP