首页 > 解决方案 > 分叉后 malloc 在父子进程中返回相同的地址

问题描述

fork 后在父子进程中调用 malloc 时,结果因操作系统而异。

这是一个简单的程序来说明这一点:

#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>

void malloctest(int cont, int value)
{
    int max = 1;
    int *var1 = malloc(sizeof(int));
    if(var1 == NULL) 
        exit(EXIT_FAILURE);
    
    *var1 = value;
    sleep(value);   
    printf("pid=%d, ppid=%d, address=%p, value=%d\n", getpid(), getppid(), var1, *var1);

    if (cont < max)
    {
        switch (fork())
        {
        case -1: //error
            perror("fork");
            exit(EXIT_FAILURE);
        case 0: //child            
            malloctest(cont + 1,5);
            _exit(EXIT_SUCCESS);
        default: //parent
            sleep(1);
            malloctest(cont + 1,1);

            wait(NULL);
        }
    }
}

int main(int argc, char const *argv[])
{
    malloctest(0,0);
}

在 macOSDarwin 20.6.0 Darwin Kernel Version 20.6.0: Wed Jun 23 00:26:31 PDT 2021; root:xnu-7195.141.2~5/RELEASE_X86_64 i386中,malloc 返回不同的地址

pid=63430, ppid=60230, address=0x7f9199405bd0, value=0
pid=63430, ppid=60230, address=0x7f9199504080, value=1
pid=63431, ppid=63430, address=0x7f91995041e0, value=5

而在 Linux 中Linux 4.15.0-58-generic #64-Ubuntu SMP Tue Aug 6 11:12:41 UTC 2019 x86_64,malloc 在父子节点中返回相同的地址

pid=10314, ppid=3797, address=0x561284e5b260, value=0
pid=10314, ppid=3797, address=0x561284e5b690, value=1
pid=10315, ppid=10314, address=0x561284e5b690, value=5

这有什么好担心的吗?或者它只是一个实现细节,操作系统可以返回相同的地址,因为它使用写时复制技术来维护父子对象指向的值的单独副本?而 macOS 直接分配不同的地址

标签: clinuxmallocfork

解决方案


没有什么可担心的——进程是独立的,并且有独立的地址空间。除非您设置了共享内存(并且malloc()不会返回指向共享内存的指针),否则没有共享。


推荐阅读