Yes the child will have proper malloc()
ed memory.
First, know that there are two memory managers in place:
- One is the Linux kernel, which allocates memory pages to processes. This is done through the
sbrk()
system call.
- On the other hand,
malloc()
uses sbrk()
to request memory from the kernel and then manages it, by breaking it in chunks, remembering how the memory has been divided and later mark them as available when free()
ed (and at times perform something similar to garbage collection).
That said, what malloc()
does with memory is completely transparent to the Linux kernel. It's effectively just a linked list or two, which you could have implemented yourself. What the Linux kernel sees as your memory are the pages assigned to your process and their contents.
When you call fork()
(emphasis mine):
- The child process is created with a single thread--the one that called fork(). The entire virtual address space of the parent is replicated in the child, including the states of mutexes, condition variables, and other pthreads objects; the use of pthread_atfork(3) may be helpful for dealing with problems that this can cause.
- The child inherits copies of the parent's set of open file descriptors. Each file descriptor in the child refers to the same open file description (see open(2)) as the corresponding file descriptor in the parent. This means that the two descriptors share open file status flags, current file offset, and signal-driven I/O attributes (see the description of F_SETOWN and F_SETSIG in fcntl(2)).
- The child inherits copies of the parent's set of open message queue descriptors (see mq_overview(7)). Each descriptor in the child refers to the same open message queue description as the corresponding descriptor in the parent. This means that the two descriptors share the same flags (mq_flags).
- The child inherits copies of the parent's set of open directory streams (see opendir(3)). POSIX.1-2001 says that the corresponding directory streams in the parent and child may share the directory stream positioning; on Linux/glibc they do not.
So fork()
not only copy the entire virtual address space, but also all mutexes, file descriptors and basically every kind of resource the parent has opened. Part of the virtual address space copied is the linked list(s) of malloc()
. So after a fork()
, the malloc()
ed memories of both processes are equal and the information malloc()
keeps and what memory is allocated is also the same. However, they now live on separate memory pages.
Side information: One might think that fork()
is a very expensive operation. However (from the man page):
Under Linux, fork()
is implemented using copy-on-write pages, so the only penalty that it incurs is the time and memory required to duplicate the parent's page tables, and to create a unique task structure for the child.
This basically says that on fork()
ing, no actual copying is done, but the pages are marked to be copied if the child tries to modify them. Effectively, if the child only reads from that memory, or completely ignore it, there is no copy overhead. This is very important for the common fork()
/exec()
pattern.