LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-14-2007, 03:03 AM   #1
piyush.kansal
LQ Newbie
 
Registered: May 2007
Location: Pune, India
Distribution: Fedora Core
Posts: 29

Rep: Reputation: 15
Same address on heap for both child and parent process even after COPY_ON_WRITE??


Hi,
While playing with fork(), I observed a scenario on which I need some clarification. Before that, here is the program code which I ran:

Code:
#include <sys/types.h>
#include <unistd.h>

int i = 0;
int *j = NULL;
int *m = NULL;

int main()
{
	int k = 0;
	int *l = NULL;
	int *n = NULL;

	j = (int *)malloc(sizeof(int));
	m = (int *)malloc(sizeof(int));
	l = (int *)malloc(sizeof(int));
	n = (int *)malloc(sizeof(int));

	*j = 1;
	*m = 1;
	*l = 1;
	*n = 1;

	printf( "   g_&i=%u\tg_i=%u\th_&j=%u\th_j=%u\th_*j=%u\th_&m=%u\th_m=%u\th_*m=%u\n", &i, i, &j, j, *j, &m, m, *m );
	printf( "   l_&k=%u\tl_k=%u\th_&l=%u\th_l=%u\th_*l=%u\th_&n=%u\th_n=%u\th_*n=%u\n", &k, k, &l, l, *l, &n, n, *n );

	if ( 0 == fork() )
	{
		printf( "C. g_&i=%u\tg_i=%u\th_&j=%u\th_j=%u\th_*j=%u\th_&m=%u\th_m=%u\th_*m=%u\n", &i, i, &j, j, *j, &m, m, *m );
		printf( "C. l_&k=%u\tl_k=%u\th_&l=%u\th_l=%u\th_*l=%u\th_&n=%u\th_n=%u\th_*n=%u\n", &k, k, &l, l, *l, &n, n, *n );

		sleep(1);
		printf("\nCOPY_ON_WRITE will take place now\n\n");
		i = 1;
		k = 1;
		*j = 2;
		*m = 2;
		*l = 3;
		*n = 3;

		printf( "C. g_&i=%u\tg_i=%u\th_&j=%u\th_j=%u\th_*j=%u\th_&m=%u\th_m=%u\th_*m=%u\n", &i, i, &j, j, *j, &m, m, *m );
		printf( "C. l_&k=%u\tl_k=%u\th_&l=%u\th_l=%u\th_*l=%u\th_&n=%u\th_n=%u\th_*n=%u\n", &k, k, &l, l, *l, &n, n, *n );
	}
	else
	{
		printf( "P. g_&i=%u\tg_i=%u\th_&j=%u\th_j=%u\th_*j=%u\th_&m=%u\th_m=%u\th_*m=%u\n", &i, i, &j, j, *j, &m, m, *m );
		printf( "P. l_&k=%u\tl_k=%u\th_&l=%u\th_l=%u\th_*l=%u\th_&n=%u\th_n=%u\th_*n=%u\n", &k, k, &l, l, *l, &n, n, *n );

		sleep(1);

		printf( "P. g_&i=%u\tg_i=%u\th_&j=%u\th_j=%u\th_*j=%u\th_&m=%u\th_m=%u\th_*m=%u\n", &i, i, &j, j, *j, &m, m, *m );
		printf( "P. l_&k=%u\tl_k=%u\th_&l=%u\th_l=%u\th_*l=%u\th_&n=%u\th_n=%u\th_*n=%u\n", &k, k, &l, l, *l, &n, n, *n );
	}
}
Here, I was just trying to figure out the effect of COPY_ON_WRITE on the addresses of the various kinds of variables used here after fork() and here is the output which I got:

Code:
[piyushkansal@localhost Forking]$ ./fork
   g_&i=134519608       g_i=0   h_&j=134519612  h_j=166604808   h_*j=1  h_&m=134519616  h_m=166604824   h_*m=1
   l_&k=3220329380      l_k=0   h_&l=3220329376 h_l=166604840   h_*l=1  h_&n=3220329372 h_n=166604856   h_*n=1
C. g_&i=134519608       g_i=0   h_&j=134519612  h_j=166604808   h_*j=1  h_&m=134519616  h_m=166604824   h_*m=1
C. l_&k=3220329380      l_k=0   h_&l=3220329376 h_l=166604840   h_*l=1  h_&n=3220329372 h_n=166604856   h_*n=1
P. g_&i=134519608       g_i=0   h_&j=134519612  h_j=166604808   h_*j=1  h_&m=134519616  h_m=166604824   h_*m=1
P. l_&k=3220329380      l_k=0   h_&l=3220329376 h_l=166604840   h_*l=1  h_&n=3220329372 h_n=166604856   h_*n=1

COPY_ON_WRITE will take place now

C. g_&i=134519608       g_i=1   h_&j=134519612  h_j=166604808   h_*j=2  h_&m=134519616  h_m=166604824   h_*m=2
C. l_&k=3220329380      l_k=1   h_&l=3220329376 h_l=166604840   h_*l=3  h_&n=3220329372 h_n=166604856   h_*n=3
P. g_&i=134519608       g_i=0   h_&j=134519612  h_j=166604808   h_*j=1  h_&m=134519616  h_m=166604824   h_*m=1
P. l_&k=3220329380      l_k=0   h_&l=3220329376 h_l=166604840   h_*l=1  h_&n=3220329372 h_n=166604856   h_*n=1
Here, I have printed the variable names by prefixing them with g_ or l_ just for an indication that its a global or local variable respectively.

Now, I have got some confusion for following variables :: j, m, l, n (all pointer variables).
1. Look at row 1, col 4 and row 1, col 7 :: j and m are two global pointer variables, to which I am allocating 4 bytes of memory using malloc, so in this case, why the difference in address (166604824 - 166604808) is of 16 bytes. It should be of 4 bytes? Same is with l and n(166604856 - 166604840 = 16)?

2. As far as I know heap is a global entity from which memory is allocated or deallocated by all the different processes. As per the fork implementation, till COPY_ON_WRITE, the same memory is used by both child and parent and after that it becomes separate. Then why even after that I am getting the same address (on heap) for both child and parent?
C :: h_j=166604808 h_j=166604824
P :: h_m=166604808 h_m=166604824

Please suggest.
 
Old 07-14-2007, 10:57 AM   #2
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 31
Quoth piyush.kansal:

Quote:
Look at row 1, col 4 and row 1, col 7 :: j and m are two global pointer variables, to which I am allocating 4 bytes of memory using malloc, so in this case, why the difference in address (166604824 - 166604808) is of 16 bytes. It should be of 4 bytes?
When you do a malloc(), additional bytes are used to keep track of how large the block is, among other things, so that when you do a free(), the library code will know how much to free, and so on. There can also be issues of aligning the memory address returned to you on a boundary of a specific power of 2.

Quote:
As far as I know heap is a global entity from which memory is allocated or deallocated by all the different processes.
Fortunately, no. Each process has its own heap, and each process has its own address space. For any specific process, a given address will map to a physical address within a block of memory allocated to the process, or will map to an address within a block of memory that has temporarily been swapped out (in which case that block of memory will be swapped back in before the process is allowed to continue), or won't map to anything belonging to the process, in which case the process will trap with a (memory) segment violation.

So if two processes have pointers whose content is identical, they won't map to the same physical memory (assuming that the "copy on write" event has occurred).

Hope this helps.
 
Old 07-14-2007, 01:54 PM   #3
piyush.kansal
LQ Newbie
 
Registered: May 2007
Location: Pune, India
Distribution: Fedora Core
Posts: 29

Original Poster
Rep: Reputation: 15
Quote:
When you do a malloc(), additional bytes are used to keep track of how large the block is, among other things, so that when you do a free(), the library code will know how much to free, and so on. There can also be issues of aligning the memory address returned to you on a boundary of a specific power of 2.
So, I think the no of bytes used for this tracking will depend on the library we are using and not on OS. For eg, if I am using the same library(customized for Win) on Windows(obviously using some different system call in place of fork), then also 12 bytes will be used for tracking purpose? Or it depends on OS too?
 
Old 07-14-2007, 02:51 PM   #4
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Misunderstanding about virtual memory?

Hi -

I'm not sure I understand (all of?) your question(s) ... but ...

Quote:
C :: h_j=166604808 h_j=166604824
P :: h_m=166604808 h_m=166604824
<= Heap address "h_j=166604808" in one process maps to a completely
different physical location than identical address "h_j=166604808"
in another process
I hope that helps ...
... and apologies in advance if that doesn't address (pardon the pun) your original question...
 
Old 07-15-2007, 07:42 AM   #5
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 31
Quoth piyush.kansal:

Quote:
the no of bytes used for this tracking will depend on the library we are using and not on OS. For eg, if I am using the same library(customized for Win) on Windows(obviously using some different system call in place of fork), then also 12 bytes will be used for tracking purpose? Or it depends on OS too?
You are correct. It does not depend on the OS.
 
Old 07-16-2007, 10:18 AM   #6
piyush.kansal
LQ Newbie
 
Registered: May 2007
Location: Pune, India
Distribution: Fedora Core
Posts: 29

Original Poster
Rep: Reputation: 15
Quote:
You are correct. It does not depend on the OS.
Ok thanks.
Since we have already carried out discussion to this level, so I also wanted to bring one thing to your notice, just for information sharing and that is:
1. Only 4B are used for tracking purpose and not all.
2. If we are allocating less than or equal to 12B then, always 12B will be allocated for data + 4 for tracking purpose = 16B.
3. The moment we start going upwards, then data bytes are incremented by 8 + 4 for tracking i.e if I am allocating 13B, then 20B will be allocated for data(12+8) + 4 for tracking = 24B.

Here is the program by which I find out this:
Code:
#include <sys/types.h>
#include <unistd.h>

int main()
{
        int *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *f = NULL, *g = NULL;

        a = (int *)malloc(1);
        b = (int *)malloc(12);
        c = (int *)malloc(13);
        d = (int *)malloc(20);
        e = (int *)malloc(21);
        f = (int *)malloc(4);
        g = (int *)malloc(1);

        printf( "a=%u\tb=%u\tc=%u\td=%u\te=%u\tf=%u\tg=%u\n", a, b, c, d, e, f, g );
}
Code:
[piyushkansal@localhost Forking]$ ./addonheap2
a=140816392     b=140816408     c=140816424     d=140816448     e=140816472     f=140816504     g=140816520
As you can see here, for "b" I allocate 12B. Still, the difference is address is 140816424-140816408=16B.
But, the moment I go for 13 in "c", it goes to 140816448-140816424=24. Now, to verify whether still 4B are for tracking, I am allocating 20B again in "d" and still the difference is 140816472-140816448=24.
 
Old 07-16-2007, 10:26 AM   #7
piyush.kansal
LQ Newbie
 
Registered: May 2007
Location: Pune, India
Distribution: Fedora Core
Posts: 29

Original Poster
Rep: Reputation: 15
Quote:
I'm not sure I understand (all of?) your question(s) ... but ...
Actually, I had a doubt whether we have a global heap for all the processes or local heap, local to a process. So, that thing is clear now.
Neways, thanks for the effort.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
child process usses same amount of ram as parent process socialjazz Programming 7 10-19-2006 05:48 PM
When I kill parent process, child isn't killed BengeBoy Linux - Software 0 08-19-2004 04:38 PM
Bash Scripting - child process affecting parent process mthaddon Linux - General 1 05-02-2004 01:19 PM
about parent and child process winwar Solaris / OpenSolaris 3 07-23-2003 06:07 AM
child and parent process error jdevanand Programming 1 04-29-2002 08:13 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:35 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration