Home > Archive > Unix Programming > January 2008 > fork() and malloc()
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
fork() and malloc()
|
|
| vippstar@gmail.com 2008-01-19, 7:12 pm |
| Hello again.
I have this small isue with fork() and malloc()
According to APUE, fork() makes an exact copy of the parent process
except the text segment which they both share.
Therefore, assuming it copies the dynamically allocated memory, I have
a memory leak here:
-- snip.c --
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(void) {
pid_t pid;
void *ptr;
ptr = malloc(1024);
if(ptr == NULL) {
perror("malloc");
exit(-1);
}
if((pid = fork()) == -1) {
perror(NULL);
free(ptr);
exit(-1);
} else if(pid == 0)
exit(0);
printf("Hello, world\n");
free(ptr);
exit(0);
}
-- snip.c --
Because 'ptr' is not freed in the child process.
Please help me with this matter. (Am I correct? yes/no, what should I
do, etc)
| |
| Syren Baran 2008-01-19, 7:12 pm |
| vippstar@gmail.com schrieb:
> Hello again.
> Therefore, assuming it copies the dynamically allocated memory, I have
> a memory leak here:
> -- snip.c --
<snap>
> } else if(pid == 0)
> exit(0);
> printf("Hello, world\n");
> free(ptr);
> exit(0);
> }
> -- snip.c --
>
> Because 'ptr' is not freed in the child process.
>
> Please help me with this matter. (Am I correct? yes/no, what should I
> do, etc)
Yes, you have a memory leak for about a split second, until the OS
reclaims the resources.
As to what you should do. If you encounter strange little green aliens,
stay calm. (Sorry, i didnt quite understand that question)
| |
| Bin Chen 2008-01-19, 10:15 pm |
| On 1=D4=C220=C8=D5, =C9=CF=CE=E75=CA=B148=B7=D6, vipps...@gmail.com wrote:
> Hello again.
>
> I have this small isue with fork() and malloc()
> According to APUE, fork() makes an exact copy of the parent process
> except the text segment which they both share.
> Therefore, assuming it copies the dynamically allocated memory, I have
> a memory leak here:
> -- snip.c --
> #include <stdio.h>
> #include <stdlib.h>
> #include <sys/types.h>
> #include <unistd.h>
>
> int main(void) {
>
> pid_t pid;
> void *ptr;
>
> ptr =3D malloc(1024);
> if(ptr =3D=3D NULL) {
> perror("malloc");
> exit(-1);
> }
>
> if((pid =3D fork()) =3D=3D -1) {
> perror(NULL);
> free(ptr);
> exit(-1);
> } else if(pid =3D=3D 0)
> exit(0);
> printf("Hello, world\n");
> free(ptr);
> exit(0);}
>
> -- snip.c --
>
> Because 'ptr' is not freed in the child process.
>
> Please help me with this matter. (Am I correct? yes/no, what should I
> do, etc)
No, the exit(0) will tell the OS to reclaim the space.
| |
| Logan Shaw 2008-01-19, 10:15 pm |
| vippstar@gmail.com wrote:
> I have this small isue with fork() and malloc()
> According to APUE, fork() makes an exact copy of the parent process
> except the text segment which they both share.
> Therefore, assuming it copies the dynamically allocated memory, I have
> a memory leak here:
> -- snip.c --
> #include <stdio.h>
> #include <stdlib.h>
> #include <sys/types.h>
> #include <unistd.h>
>
> int main(void) {
>
> pid_t pid;
> void *ptr;
>
> ptr = malloc(1024);
> if(ptr == NULL) {
> perror("malloc");
> exit(-1);
> }
>
> if((pid = fork()) == -1) {
> perror(NULL);
> free(ptr);
> exit(-1);
> } else if(pid == 0)
> exit(0);
> printf("Hello, world\n");
> free(ptr);
> exit(0);
> }
> -- snip.c --
>
> Because 'ptr' is not freed in the child process.
I am going to assume you mean this example to reflect a situation
where you would have some long-lived processing going on during
the time between the fork() and the exit()s, during which you'd
miss the memory that would be temporarily unavailable.
In that case, yes, it is a leak.
This is a bit of a conundrum at first glance, since ptr has the
same value in both processes after the fork, and thus it might
not be obvious how it can point to two separate regions of memory.
The answer is that virtual memory is required in order to implement
Unix's fork(). That means that although the variable ptr contains
the same virtual address in both processes, it is mapped to two
different physical addresses[1] in each one.
The solution is to free any resources (not just memory -- also
open files, for example) that you don't need, after you've
fork()ed. In practice, a good technique can be to avoid allocating
much of anything until after you're fork()ed, thus reducing the
worry about having to free things all over the place.
- Logan
[1] At least potentially; many if not most Unix kernels these
days optimize away the copy by taking advantage of the
MMU's ability to detect writes to memory and copying only
when a write is done. Thus they could share the same
physical address until one or the other process tries
to write to the memory. Further complicating matters
is that the mapping between virtual and physical addresses
changes over time for other reasons as well. But conceptually,
the two pointers point to "different memory" even though they
have the same mathematical value.
| |
| vippstar@gmail.com 2008-01-20, 8:12 am |
| On Jan 20, 5:43 am, Logan Shaw <lshaw-use...@austin.rr.com> wrote:
> vipps...@gmail.com wrote:
>
>
>
>
>
>
> I am going to assume you mean this example to reflect a situation
> where you would have some long-lived processing going on during
> the time between the fork() and the exit()s, during which you'd
> miss the memory that would be temporarily unavailable.
That is what I ment indeed.
> In that case, yes, it is a leak.
>
> This is a bit of a conundrum at first glance, since ptr has the
> same value in both processes after the fork, and thus it might
> not be obvious how it can point to two separate regions of memory.
> The answer is that virtual memory is required in order to implement
> Unix's fork(). That means that although the variable ptr contains
> the same virtual address in both processes, it is mapped to two
> different physical addresses[1] in each one.
>
> The solution is to free any resources (not just memory -- also
> open files, for example) that you don't need, after you've
> fork()ed. In practice, a good technique can be to avoid allocating
> much of anything until after you're fork()ed, thus reducing the
> worry about having to free things all over the place.
I've also thought about having a data structure that holds all the
allocated pointers and a function freeall().
Then I would fork() and freeall().
But this is unnecessary, as you noted it's better to wait all fork()'s
to be done and then allocate memory.
Thanks for clearing this up.
|
|
|
|
|