具体来说,fork()如何处理Linux中malloc()动态分配的内存?

pcd*_*623 32 c linux heap malloc fork

我有一个包含父进程和子进程的程序.在fork()之前,父进程调用malloc()并用一些数据填充数组.在fork()之后,孩子需要那些数据.我知道我可以使用管道,但以下代码似乎有效:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main( int argc, char *argv[] ) {
    char *array;
    array = malloc( 20 );
    strcpy( array, "Hello" );
    switch( fork() ) {
    case 0:
        printf( "Child array: %s\n", array );
        strcpy( array, "Goodbye" );
        printf( "Child array: %s\n", array );
        free( array );
        break;
    case -1:
        printf( "Error with fork()\n" );
        break;
    default:
        printf( "Parent array: %s\n", array );
        sleep(1);
        printf( "Parent array: %s\n", array );
        free( array );
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

Parent array: Hello
Child array: Hello
Child array: Goodbye
Parent array: Hello
Run Code Online (Sandbox Code Playgroud)

我知道在堆栈上分配的数据在子代中可用,但似乎堆上分配的数据也可供子代使用.同样,孩子无法修改堆栈上的父数据,子进程无法修改父数据.所以我假设孩子获得了自己的堆栈和堆数据副本.

在Linux中总是这样吗?如果是这样,支持这个的文档在哪里?我检查了fork()手册页,但没有特别提到堆上动态分配的内存.

谢谢

aby*_*byx 36

为进程分配的每个页面(无论是在其上还是堆上的堆栈的虚拟内存页面)都会被复制,以便分叉进程能够访问它.

实际上,它没有在开始时被复制,它被设置为Copy-on-Write,这意味着一旦其中一个进程(父进程或子进程)尝试修改它被复制的页面,这样它们就不会互相伤害,并且仍然可以访问fork()的所有数据.

例如,代码页,即实际可执行文件被映射到内存中的代码页,通常是只读的,因此可以在所有分叉进程中重用 - 它们不会再被复制,因为没有人在那里写,只能读,所以永远不需要写时复制.

更多信息可在此处此处获得.

  • 不可能 - 进程无法再使用此内存进行通信. (3认同)

Noa*_*ins 5

在分叉之后,孩子完全独立于父级,但是可以继承某些作为父级副本的事物。对于堆,子级在概念上会在派生时拥有父堆的副本。但是,修改孩子地址空间中的头部只会修改孩子的副本(例如,通过写时复制)。

至于文档:我注意到文档通常会声明所有内容都已复制,除了等等,等等。