Click here to Skip to main content
15,881,092 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
Hi all,

When an object is created the size of the object is equal to the size of member

variable.For every instance of a class there will be only one memory for

function.Then where the function is storing.How the object know the reference of the

memory of corresponding function.When an object is allocating with "new" what is

actually happening internally.Please help me.

Thanks in advance
Posted
Comments
elgaabeb 17-Nov-11 10:30am    
could you accept the answer if you like it ?
Thx.

Hi,

Here is resume on programs memory structure :

-Stack : It is used for holding the return address at function calls, arguments passed and local variable for functions; it also stores the current state of the CPU.
-Heap : Memory area is a region of free memory from where memory is allocated for the dynamic allocation in C++.
-Global Variable : This space is used to store the global variable used in the program.
-Program Code : This region holds the compiled code of the program.

For member functions, the code for those is not different from free-function code in terms of where it goes in the executable image : "Program Code" Area.

After all, a member function is basically a free function with an implicit "this" pointer as its first argument.


When an object is allocating with "new", a new instance of members vars are allocated in the Heap but a member function code is associated to the class and stored just one time in "Program Code" Area.
 
Share this answer
 
v2
Well as Chuck has given you a hint, the function is not stored inside the object itself. The this pointer is the key to all. The "this" pointer is passed to the function as the first argument when it is called.

So lets take an example the class SampleCode.

C++
class SampleCode
{
private:
	int _int;

public:
	void foo()
	{
		++_int;
	}

	void bar()
	{
		int i = 0;
	}
};

void caller()
{
	SampleCode* p = NULL;
	p->foo();
	p->bar();
}class SampleCode
{
private:
	int _int;

public:
	void foo()
	{
		++_int;
	}

	void bar()
	{
		int ibar = 0;
	}

	static void foo_bar()
	{
		int ifoo_bar = 0;
	}
};

void called()
{
	int icalled = 0;
}

void caller()
{
	SampleCode* p = 0;
	p->foo();
	p->bar();
	p->foo_bar();
}


So the algorithm is that this code is converted to something like:

1. All Function (Member or not) are executable, but the code does not change. So store them in the Text segment of the output object file. Text segments are read only segments.
2. When a function is called the parameters are passed to it by stack. So when a non static member function is called then the
C++
this
pointer is pushed into the stack behind the scene.
3. Inside the member function any member variable is referenced relative to the
C++
this
pointer.
4. This is not passed to the static member functions. This is the reason static functions cannot use any member variable. Cause they do not contain a reference to this the don't know where the member variable resides in the code.
When we see the example of the code p->foo()
Now suppose you have allocated the object. So after the constructor call is done and "p" points to a proper memory location, the this will also be know. So when we call the function something like this happens.
A. Push this to the stack.
B. Call foo.
foo( ) uses a member variable,
but here we made a mistake, we did not allocate the pointer. So "this" basically means a garbage value. So this line will crash, as the code tries to find _int variable relative to "this" pointer.
5. Now lets consider the example p->bar()
(This line will not crash)
We are calling a function here, but we are not using a member variable. So we don't mind if the this pointer is garbage.
This will not cause a crash. The code for function is not stored in the allocated object that's why, if it were stored then there would have been a crash.
Now we will compile it:
Allow me to use a real assembled output.(Visual Studio 2008)
Just see the bold lines
C++


PUBLIC ?called@@YAXXZ ; Function called declared
_TEXT SEGMENT ;TEXT segment, code for function called
_icalled$ = -4 ; size = 4
?called@@YAXXZ PROC ; called, COMDAT

; 24 : {

push ebp
mov ebp, esp
push ecx

; 25 : int icalled = 0;

mov DWORD PTR _icalled$[ebp], 0

; 26 : }

mov esp, ebp
pop ebp
ret 0
?called@@YAXXZ ENDP ; Code for called Ends here
_TEXT ENDS
;Member function definition starts here
PUBLIC ?foo_bar@SampleCode@@SAXXZ ; SampleCode::foo_bar
PUBLIC ?bar@SampleCode@@QAEXXZ ; SampleCode::bar
PUBLIC ?foo@SampleCode@@QAEXXZ ; SampleCode::foo
;Member function definition ends here
;Function caller definition starts here
PUBLIC ?caller@@YAXXZ ; caller
;Function caller definition ends here
; function caller TEXT segment, i.e. code start
_TEXT SEGMENT
_p$ = -4 ; size = 4
?caller@@YAXXZ PROC ; caller, COMDAT

; 29 : {

push ebp
mov ebp, esp
push ecx

; 30 : SampleCode* p = 0;

mov DWORD PTR _p$[ebp], 0

; 31 : p->foo();

mov ecx, DWORD PTR _p$[ebp] ;this is ecx register
call ?foo@SampleCode@@QAEXXZ ; SampleCode::foo

; 32 : p->bar();

mov ecx, DWORD PTR _p$[ebp]
call ?bar@SampleCode@@QAEXXZ ; SampleCode::bar

; 33 : p->foo_bar(); No this is passed for static function

call ?foo_bar@SampleCode@@SAXXZ ; SampleCode::foo_bar

; 34 : }

mov esp, ebp
pop ebp
ret 0
?caller@@YAXXZ ENDP
; function caller TEXT segment , i.e. code end
; Function compile flags: /Odtp
_TEXT ENDS
; COMDAT ?foo@SampleCode@@QAEXXZ
_TEXT SEGMENT
_this$ = -4 ; size = 4
?foo@SampleCode@@QAEXXZ PROC ; SampleCode::foo, COMDAT
; _this$ = ecx

; 8 : {

push ebp
mov ebp, esp
push ecx
mov DWORD PTR _this$[ebp], ecx ;This is populated from the stack as the function SampleCode::foo is called

; 9 : ++_int;

mov eax, DWORD PTR _this$[ebp]
mov ecx, DWORD PTR [eax]
add ecx, 1
mov edx, DWORD PTR _this$[ebp]
mov DWORD PTR [edx], ecx

; 10 : }

mov esp, ebp
pop ebp
ret 0
?foo@SampleCode@@QAEXXZ ENDP ; SampleCode::foo
; Function compile flags: /Odtp
_TEXT ENDS
; COMDAT ?bar@SampleCode@@QAEXXZ
_TEXT SEGMENT
_this$ = -8 ; size = 4
_ibar$ = -4 ; size = 4
?bar@SampleCode@@QAEXXZ PROC ; SampleCode::bar, COMDAT
; _this$ = ecx

; 13 : {

push ebp
mov ebp, esp
sub esp, 8
mov DWORD PTR _this$[ebp], ecx

; 14 : int ibar = 0;

mov DWORD PTR _ibar$[ebp], 0

; 15 : }

mov esp, ebp
pop ebp
ret 0
?bar@SampleCode@@QAEXXZ ENDP ; SampleCode::bar
; Function compile flags: /Odtp
_TEXT ENDS
; COMDAT ?foo_bar@SampleCode@@SAXXZ
_TEXT SEGMENT
_ifoo_bar$ = -4 ; size = 4
?foo_bar@SampleCode@@SAXXZ PROC ; SampleCode::foo_bar, COMDAT

; 18 : {

push ebp
mov ebp, esp
push ecx

; 19 : int ifoo_bar = 0;

mov DWORD PTR _ifoo_bar$[ebp], 0

; 20 : }

mov esp, ebp
pop ebp
ret 0
?foo_bar@SampleCode@@SAXXZ ENDP ; SampleCode::foo_bar
_TEXT ENDS
END
C++

 
Share this answer
 
Comments
Nish Nishant 17-Nov-11 13:46pm    
Good detailed response. My 5.

Needs a bit of formatting though.
BrainlessLabs.com 17-Nov-11 14:00pm    
Ya I guess so. Next time I will be more careful.
Chuck O'Toole 17-Nov-11 14:05pm    
Oh I disagree, this is a terrible response. The OP is clearly trying to learn yet this example starts off by showing a NULL for the object, not allocating it and then jumps into assembly code to show some obscure point about not crashing for one reason or another. Talk about confusing someone who's trying to learn. My 1.

void caller()
{
SampleCode* p = NULL;
p->foo();
p->bar();
}
Richard MacCutchan 17-Nov-11 15:16pm    
I agree with Chuck, what on earth is a beginner expected to make of all that assembly code? And PLEASE if you must post code then format it properly; as I have done on your behalf. gave up, there's too much.
Albert Holguin 17-Nov-11 19:21pm    
Agree with Chuck... If the OP is trying to learn C++, what makes you think he knows assembly?
Start here : The this pointer[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900