Newbie Question about Value and Reference Types

G

Gabor Törö

Hi!

I'm new to vb.net (and to programming as well) and last night I tried
to make my own picture of the difference of value and reference types.


What I find out is that the main difference is how the CLR handles the
memory for this types. If a new instance of a value type is generated
then for this instance an address exist which points to a formatted
chunk of data on the stack. This adress which points on the stack can
be regarded as the name of the instance which is connected to the name
of the instance in the source code.


When ever the program execution leaves the scope of the instance the
used memory on the stack will immediately be reclaimed and the instance
no longer exists.


If a new instance of a reference type is generated then the same
happens with the stack with the difference that the data on the stack
is an adresse which points to the heap where the real data of the
instance is. If the instance variable is set to nothing or if the
instance is out of scope then the used memory on the stack is again
immediately reclaimed but the instance still lives due to the data on
the heap. First if the garbage collector decides to clean up instances
which no longer are reachable by the application then the instance will
be removed totally from the memory.


If an instance is passed to an implementation then one has to distinct
the four cases:


1) ByVal Value Type
2) ByVal Reference Type
3) ByRef Value Type
4) ByRef Reference Type


If an instance is passed by value semantics then a copy of the data on
the stack is made and the adress of this copy is passed to the
implementation while by reference semantics pass the adress of the
original data on the stack. If the instance is a value type then the
implementation has no access to the original instance at all as the
implementation only get the name (adress) of the copy on the stack.


But if the instance is a reference type then again the implementatoin
gets a adress of the copy on the stack but the data on the stack points
to the real data on the heap. So this way the implementation has access
to the data of original instance. What the implemantaion can do not is
to change the target of the reference of the instance. That means it
can not change the data on the stack of the original instance. The
pointer to the place to the heap can not be changed.


Last but not least one have the case where a reference type is passed
by reference. Then the implementation not only can modify the data on
the heap. As the implementation gets the original adress on the stack
where the location of the heap's date is found the implementation can
chage this value and therefore can the reference variable point to a
totally different place on the heap. That means the reference variable
can point to a different instance.


Correct?


If so then I have another question: If a reference type is passed by
reference to a procedure and within this procedure a new instance of
the same type is generated and assigned to the passed reference
variable what happens to the instacne on the heap if the program
execution leaves the procedure? I think the original instacne on the
heap is now in danger to be killed by the garbage collector as no
reference points to it anymore:


Sub Main()
....
Dim a As New Object
....
Test(a)
.....
End Sub
....
Sub Test(ByRef a As Object)
Dim b As New Object
a=b
End Sub


Correct?


GFM GToeroe
 
C

Chris Dunaway

Gabor said:
If a new instance of a value type is generated
then for this instance an address exist which points to a formatted
chunk of data on the stack. This adress which points on the stack can

There is no pointer involved. The actual value is stored on the stack,
not an address that points to the value.
If an instance is passed by value semantics then a copy of the data on
the stack is made and the adress of this copy is passed to the
implementation while by reference semantics pass the adress of the
original data on the stack. If the instance is a value type then the
implementation has no access to the original instance at all as the
implementation only get the name (adress) of the copy on the stack.

Again, the actual value is passed not an address that points to it.

Check out this excellent article by Jon Skeet:

http://www.yoda.arachsys.com/csharp/memory.html
 
G

gfm

If a new instance of a value type is generated
There is no pointer involved. The actual value is stored on the stack,
not an address that points to the value.

But how does a called procedure know where it should find the passed
value type? Or does it assume it lays on the top of the stack?

GFM GToeroe
 
C

Chris Dunaway

Generally speaking, the calling procedure pushes the values of the
parameters onto the stack. In the case of value types, the actual
value is pushed onto the stack. For reference types the address of the
object. Once inside the calling procedure, those values are popped off
of the stack in reverse order so they can be used inside the procedure.


That is over-simplifying it, to be sure, but that is generally what
happens. I'm sure there are differences when an item is passed by
value or passed by reference and whether or not the item being passed
in is a value type or reference type.

I'm sure Jon Skeet will be along soon to clarify it as this is a
subject that he knows so well. :)
 
D

david

You're pretty much correct about all this, but one quibble.
If an instance is passed by value semantics then a copy of the data on
the stack is made and the adress of this copy is passed to the
implementation while by reference semantics pass the adress of the
original data on the stack.

The address of the copy isn't passed to the implementation. Rather, the
caller simply puts the value on the stack, and the caller *already*
knows where to find the value relative to the stack pointer. IAW,

public void foo(int i, int j, int k) {

A caller doesn't need to send foo the addresses of i,j and k. It just
sets up the stack correctly, and the foo function knows that it can find
i,j and k at the appropriate positions on the stack.

If so then I have another question: If a reference type is passed by
reference to a procedure and within this procedure a new instance of
the same type is generated and assigned to the passed reference
variable what happens to the instacne on the heap if the program
execution leaves the procedure? I think the original instacne on the
heap is now in danger to be killed by the garbage collector as no
reference points to it anymore:

Correct.
 
D

david

There is no pointer involved. The actual value is stored on the stack,
not an address that points to the value.

Six of one, 1/2 dozen of the other. I don't think the two of you are
actually disagreeing here. The location of an item on the stack is
itself a memory address, and the code in question uses that address to
find the value type on the stack (in this case a location relative to
the stack pointer).

I'm pretty sure that's all the OP is trying to say here.
Check out this excellent article by Jon Skeet:

http://www.yoda.arachsys.com/csharp/memory.html

Agreed.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top