Shedding some light on memory allocation of value types and reference types and demonstrating the effect on the values when reference types are passed by value or passed by reference.
using System; namespace TestApp { class Program { static void Main(string[] args) { Sample originalSample = new Sample(10, "Original String"); Console.WriteLine("Printing original values ..."); Console.WriteLine("Int: " + originalSample.myInt); Console.WriteLine("String: " + originalSample.myString); // Pass originalSample by value TestMethod1(originalSample); Console.WriteLine("After TestMethod1 ..."); Console.WriteLine("Int: " + originalSample.myInt); Console.WriteLine("String: " + originalSample.myString); // Pass originalSample by ref TestMethod2(ref originalSample); Console.WriteLine("After TestMethod2 ..."); Console.WriteLine("Int: " + originalSample.myInt); Console.WriteLine("String: " + originalSample.myString); Console.Read(); } static void TestMethod1(Sample a) { a = new Sample(); a.myInt = 20; a.myString = "TestMethod1"; } static void TestMethod2(ref Sample a) { a = new Sample(); a.myInt = 30; a.myString = "TestMethod2"; } } }
Program output:
Explanation:
In Main()
Let us assume that originalSample is allocated memory on the heap at location x000000
HEAP location x000000
———————
myInt 10
myString Original String
STACK
Hence the value of originalSample on the stack will be
Variable Value
————– ——-
originalSample x000000
In TestMethod1()
ref keyword is not used
What does this mean?
It means ‘a’ is local to TestMethod1. Hence a will be created on the stack as a COPY of originalSample.
The value of a on the stack will be the same as the value of the passed variable i.e. originalSample.
This value is nothing but the address on heap of originalSample
STACK
Variable Value
————– ——-
originalSample x000000
a x000000
HEAP location x000000
———————
myInt 10
myString Original String
Now if the following statements are executed
a.myInt = 20;
a.myString = "TestMethod1";
Then this will change the object at heap location x000000. But originalSample resides at x000000.
So if the above changes are made, it will change the contents of originalSample.
However, to demonstrate the difference between pass by value and ref, I have assigned a new Sample() to a.
a = new Sample();
When this runs, the new keyword has the effect of allocating new location on the heap. And now a would point to this new location.
So lets assume, new memory is allocated to a on the heap at x000004
So now the contents of the heap and stack will be as follows
HEAP location x000000
———————
myInt 10
myString Original String
HEAP location x000004
———————
myInt 0
myString ""
STACK
Variable Value
————– ——-
originalSample x000000
a x000004
a.myInt = 20;
a.myString = "TestMethod1";
Now since we are making changes to a, the contents of heap location x000004 will be affected as follows:
HEAP location x000004
———————
myInt 20
myString TestMethod1
Thus a different area of the heap is affected and originalSample remains unchanged.
Thus pass by value will not change the originalSample as long as we create a new Sample() and assign it to local variable and make changes to it.’
In TestMethod2()
ref keyword is used
What does this mean?
It means ‘a’ is a reference to originalSample. Hence a will be created on the stack as a REFERENCE of originalSample.
The value of a on the stack will be the reference to originalSample and not value of originalSample
STACK
Variable Value
————– ——-
originalSample x000000
a originalSample …. Points to originalSample which in turn points to heap location x000000
HEAP location x000000
———————
myInt 10
myString Original String
Now if the following statements are executed
a.myInt = 20;
a.myString = "TestMethod1";
Then this will change the object at heap location x000000. But originalSample resides at x000000.
So if the above changes are made, it will change the contents of originalSample.
Thus whether the value is passed by value or reference, any changes made to its member variables will be reflected.
However, to demonstrate the difference between pass by value and ref, I will assign a new Sample() to a.
a = new Sample();
The new keyword has the effect of allocating new location on the heap.
So lets assume, new memory is allocated to a on the heap at x000004
Now a should point to this new location.
However a is a reference to originalString.
Thus originalString will now point to the new location
So now the contents of the heap and stack will be as follows
HEAP location x000000
———————
myInt 10
myString Original String
HEAP location x000004
———————
myInt 0
myString ""
STACK
Variable Value
————– ——-
originalSample x000004
a originalSample
Now we can see that there is no variable on stack pointing to x000000.
Hence, it will be garbage collected in the next garbage collector cycle.
a.myInt = 30;
a.myString = "TestMethod2";
Now since we are making changes to a, the contents of heap location x000004 will be affected as follows:
HEAP location x000004
———————
myInt 20
myString TestMethod1
However, since a is reference to originalString, both pointing to the same location, we can see that originalString has been eventually modified.
Thus pass by reference will change the originalSample.
Thus we can see the effect on reference variables when they are passed by value or passed by reference.
Conclusion:
Reference type data whether passed by value or reference will change if the changes are made directly to the passed variable rather than creating a copy.
If a variable is passed by VALUE and a copy of the variable is created in the called method, changes made to the copy WILL NOT be reflected in the original variable.
If a variable is passed by REFERENCE and a copy of the variable is created in the called method, changes made to the copy WILL not be reflected in the original variable.







