免费注册 查看新帖 |

Chinaunix

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

[C++] vfork导致内存释放的问题,fork没有这个问题,为何? [复制链接]

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2017-01-02 10:26 |只看该作者 |倒序浏览
最近遇到这样的一个奇怪错误:

#include<stdio.h>
#include<unistd.h>
int main()
{
    int* pi=new int(5);
    int i=5;
    pid_t id=vfork();
    if(id>0)//father
    {
        *pi=4;
        i=4;
        printf("father set i=%d, *pi=%d\n",i, *pi);
        sleep(2);
        printf("father get i=%d, *pi=%d\n",i, *pi);
        delete pi;
    }
    else//child
    {
        sleep(1);
        printf("child get i=%d, *pi=%d\n",i, *pi);
        i=3;
        *pi=3;
        printf("child set i=%d, *pi=%d\n",i, *pi);
    }
    return 0;
}

用vfork的时候,我期待i和pi是被父子进程共享的,所以父进程改了值,子进程就能用到,运行这个程序:
$ g++ myvshare.cpp && ./a.out
  1. child get i=5, *pi=5
  2. child set i=3, *pi=3
  3. father set i=4, *pi=4
  4. father get i=4, *pi=4
  5. *** Error in `./a.out': free(): invalid pointer: 0xb75f9000 ***
  6. ======= Backtrace: =========
  7. /lib/i386-linux-gnu/libc.so.6(+0x67257)[0xb74ae257]
  8. /lib/i386-linux-gnu/libc.so.6(+0x6d577)[0xb74b4577]
  9. /lib/i386-linux-gnu/libc.so.6(+0x6dd31)[0xb74b4d31]
  10. /usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x18)[0xb766bd98]
  11. ./a.out[0x8048621]
  12. /lib/i386-linux-gnu/libc.so.6(+0x15f2d4)[0xb75a62d4]
  13. ======= Memory map: ========
  14. 08048000-08049000 r-xp 00000000 08:01 1055312    /home/x/cpp/a.out
  15. 08049000-0804a000 r--p 00000000 08:01 1055312    /home/x/cpp/a.out
  16. 0804a000-0804b000 rw-p 00001000 08:01 1055312    /home/x/cpp/a.out
  17. 0859e000-085c3000 rw-p 00000000 00:00 0          [heap]
  18. b7200000-b7221000 rw-p 00000000 00:00 0
  19. b7221000-b7300000 ---p 00000000 00:00 0
  20. b73d3000-b73d5000 rw-p 00000000 00:00 0
  21. b73d5000-b73f1000 r-xp 00000000 08:01 1181015    /lib/i386-linux-gnu/libgcc_s.so.1
  22. b73f1000-b73f2000 rw-p 0001b000 08:01 1181015    /lib/i386-linux-gnu/libgcc_s.so.1
  23. b73f2000-b7445000 r-xp 00000000 08:01 1181047    /lib/i386-linux-gnu/libm-2.23.so
  24. b7445000-b7446000 r--p 00052000 08:01 1181047    /lib/i386-linux-gnu/libm-2.23.so
  25. b7446000-b7447000 rw-p 00053000 08:01 1181047    /lib/i386-linux-gnu/libm-2.23.so
  26. b7447000-b75f6000 r-xp 00000000 08:01 1180977    /lib/i386-linux-gnu/libc-2.23.so
  27. b75f6000-b75f7000 ---p 001af000 08:01 1180977    /lib/i386-linux-gnu/libc-2.23.so
  28. b75f7000-b75f9000 r--p 001af000 08:01 1180977    /lib/i386-linux-gnu/libc-2.23.so
  29. b75f9000-b75fa000 rw-p 001b1000 08:01 1180977    /lib/i386-linux-gnu/libc-2.23.so
  30. b75fa000-b75fd000 rw-p 00000000 00:00 0
  31. b75fd000-b776a000 r-xp 00000000 08:01 400094     /usr/lib/i386-linux-gnu/libstdc++.so.6.0.21
  32. b776a000-b776b000 ---p 0016d000 08:01 400094     /usr/lib/i386-linux-gnu/libstdc++.so.6.0.21
  33. b776b000-b7770000 r--p 0016d000 08:01 400094     /usr/lib/i386-linux-gnu/libstdc++.so.6.0.21
  34. b7770000-b7771000 rw-p 00172000 08:01 400094     /usr/lib/i386-linux-gnu/libstdc++.so.6.0.21
  35. b7771000-b7774000 rw-p 00000000 00:00 0
  36. b7788000-b778b000 rw-p 00000000 00:00 0
  37. b778b000-b778d000 r--p 00000000 00:00 0          [vvar]
  38. b778d000-b778e000 r-xp 00000000 00:00 0          [vdso]
  39. b778e000-b77b0000 r-xp 00000000 08:01 1180949    /lib/i386-linux-gnu/ld-2.23.so
  40. b77b0000-b77b1000 rw-p 00000000 00:00 0
  41. b77b1000-b77b2000 r--p 00022000 08:01 1180949    /lib/i386-linux-gnu/ld-2.23.so
  42. b77b2000-b77b3000 rw-p 00023000 08:01 1180949    /lib/i386-linux-gnu/ld-2.23.so
  43. bf9ca000-bf9eb000 rw-p 00000000 00:00 0          [stack]
  44. Terminated (core dupm)
复制代码

我疑惑的地方是:
1. 如果vfork共享内存的话,为什么父进程改了,子进程看起来还是用拷贝出来的一份? 反过来看起来也一样。
2. 这个 "free()" 导致的崩溃是怎么发生的? 我把vfork改成fork就没有这个错误了。奇怪

还请指点!

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
2 [报告]
发表于 2017-01-02 13:29 |只看该作者
回复 1# asker160

vfork 用错了,先去看看文档吧

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2017-01-03 09:30 |只看该作者
vfork父子进程不能同时运行吧

VFORK 挂掉的一个问题

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
4 [报告]
发表于 2017-01-03 10:50 |只看该作者
asker160 发表于 2017-01-02 10:26
最近遇到这样的一个奇怪错误:

#include

子进程退出时弹栈, 以及调用其他函数之类导致堆栈复用, pi 对应的内存被改写; 等到了父进程执行的时候, 已经不知道是什么东西了

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
5 [报告]
发表于 2017-01-03 23:26 |只看该作者
zylthinking 发表于 2017-01-03 10:50
子进程退出时弹栈, 以及调用其他函数之类导致堆栈复用, pi 对应的内存被改写; 等到了父进程执行的时候 ...

你是说,子进程和父进程共享堆栈?这也太危险了吧,怎么可能不挂掉呢? 也就是必须exit退出,绝不可以用return弹出堆栈,对吧?!

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP