|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Newbie Question about Value and Reference TypesI'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 Gabor Törö wrote:
> If a new instance of a value type is generated There is no pointer involved. The actual value is stored on the stack,> 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 not an address that points to the value. > If an instance is passed by value semantics then a copy of the data on Again, the actual value is passed not an address that points to it.> 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. Check out this excellent article by Jon Skeet: http://www.yoda.arachsys.com/csharp/memory.html >> If a new instance of a value type is generated But how does a called procedure know where it should find the passed>> 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. value type? Or does it assume it lays on the top of the stack? GFM GToeroe 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. :) On 2006-04-21, Chris Dunaway <dunaw***@gmail.com> wrote:
> Gabor Törö wrote: Six of one, 1/2 dozen of the other. I don't think the two of you are>> 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. 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. Agreed. On 2006-04-21, Gabor Törö <g**@gtoeroe.de> wrote:
You're pretty much correct about all this, but one quibble. > The address of the copy isn't passed to the implementation. Rather, the> > 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. 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. > 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:
Option strict on and detecting a listview Name
backgroundworker Is there a way to see if a file is in use? Retrieving a list of available fonts on system. ReadAllText, special characters set defaultprinter ASP.NET GRID CONTROL. DragDrop to TextBox Can't read xml to Excel (dataset.WriteXml) Problem in datagrid |
|||||||||||||||||||||||