You will learn followings:
- Pointers in C#
- Safe VS unsafe code in C#
- String is Reference Type OR Value Type
Pointers in C#
In this article we’ll discuss Pointers in C# with the help of example. In C#, you can use pointers but with unsafe keyword only. You can also check our related article of pointers and unsafe code.
A C# pointer is nothing but a variable that holds the memory address of another type.
What you'll learn:
Syntax of Pointers in C#
type *var_name;
// example is
int *var = & x;
Unsafe Codes
The Pointers in C# statements can be executed in an unsafe context. The statements marked as unsafe by using the unsafe keyword and this piece of code will run outside the control of Garbage Collector. How we can unsafe code let’s check below:
public class Program
{
static unsafe void Main(string[] args)
{
int w = 76;
int* ptr = &w;
Console.WriteLine((int)ptr);
Console.WriteLine(*ptr);
}
}
How to run unsafe codes
- Open Visual studio and create your console application
- Right click on solution and select property option.
- Go to the build tab (as shoe in below image)
- Check the “Allow unsafe code” option.
Safe VS unsafe code
Safe codes in C# runs under the Common Language Runtime's supervision (CLR) while Un-safe codes always execute outside the management of the CLR.
Conclusion:
Unsafe code execution option is only available for C# whereas in C or C++, pointers code runs under safe code.
Pointers in C# shows the memory address and execute unmanaged codes, as we have discussed above. The reason behind using the unsafe statements is that the garbage collector does not track memory addresses in an unmanaged environment.
Video on Pointers in C#:
In this article, we’ve learned how to use Pointers in C#. You can also check our related article Pointers and unsafe code. I believe after reading this article you’ll be able to use this in your daily development practices. You can also check more on Microsoft Learn.
In this article I'll explain pointers and use of unsafe code in C#. In the same example you will also understand the difference between value type and reference type (Stack / heap) so, let's move ahead and do this.
In below section I'll develop an example using unsafe code and will show how the addresses be allocated. In addition to this at the end of this article you will come to know how to build and work with unsafe code in C#.
What this will cover:
- Value type example given below.
- Reference type example using int array.
Let's check value type in below example:
We have taken int variable with value 100. We'll try to change its value with in 'UpdateNumber' function. Let's see the code and its output below:
namespace Pointer_UnsafeCode
{
class Program
{
static void Main(string[] args)
{
unsafe
{
int num = 100;
int* p = #
Console.WriteLine("Data is: {0} Address is: {1} ", num, (int)p);
Console.WriteLine("----Before calling 'UpdateNumber' method -----");
UpdateNumber(num);
Console.WriteLine("--- After calling 'UpdateNumber' method --------");
int* p2 = #
Console.WriteLine("Data is: {0} Address is: {1} ", num, (int)p2);
Console.ReadLine();
}
}
static void UpdateNumber(int num)
{
unsafe
{
num = 1111;
int* p1 = #
Console.WriteLine("Data is: {0} Address is: {1} ", num, (int)p1);
}
}
}
}
Let's check out the addresses and the value before/ after calling 'UpdateNumber' method. Whole execution has been divided in three steps. Let's discuss all these 3 steps below:
Step 1:
Data value is 100 and its address is: 1961320 which is the actual address of our variable. Next, I'll pass this value to UpdateNumber method and try to update it with in it.
Step 2:
With in UpdateNumber method, see data value is 1111 and is address is: 1961212. Now notice we have new address 1961212, which means, within method value has been changed but new instance is created, and actual variable’s value of STEP 1 will remain the same (at its own address 1961320). Let's re-confirm data value and address after executing the 'UpdateNumber' method.
Step -3:
Data Value and address is exactly similar to STEP-1. Our UpdateNumber methods has updated the value but for some separate instance not for the actual instance. Now data value which changed in Step-2, its scope is limited to UpdateNumber function only.
Conclusion
From above steps we can conclude that actual variable value did not change in 'UpdateNumber' method, and all this happened because- int is of value type in nature.
In next example I'll take Array of type int:
namespace Pointers_Array_Example
{
class Program
{
static void Main(string[] args)
{
unsafe
{
int[] listData = { 10, 20, 30 };
fixed (int* ptr = listData)
/* lets get array address using pointer */
for (int i = 0; i < 3; i++)
{
Console.WriteLine("Value at [{0}]={1} Address is [{2}]={3}", i, *(ptr + i), i, (int)(ptr + i));
}
Console.WriteLine("--- Moving to 'UpdateValue' method ----");
UpdateValue(listData);
Console.WriteLine("----After executing 'UpdateValue' method ------");
fixed (int* ptr2 = listData)
/* lets get array address in pointer */
for (int i = 0; i < 3; i++)
{
Console.WriteLine("Value at [{0}]={1} Address is [{2}]={3}", i, *(ptr2 + i), i, (int)(ptr2 + i));
}
Console.ReadKey();
}
}
static void UpdateValue(int[] listData)
{
unsafe
{
listData[1] = 1111;
fixed (int* ptr1 = listData)
for (int i = 0; i < 3; i++)
{
Console.WriteLine("Value at[{0}]={1} Address is [{2}]={3}", i, *(ptr1 + i), i, (int)(ptr1 + i));
}
}
}
}
}
In above sample we have taken int array like shown below
In above example we took int array and we'll try to change its value within step-2 i.e., in 'UpdateValue' method. Whole execution of program is divided into 3 steps. Let's discuss all three steps below.
int[] listData = { 10, 20, 30};
Step -1:
Let's check the data value and address before passing it to 'UpdateValue' method.
Refer Step -2:
Now with in 'UpdateValue' method we'll try to update value at index [1] from 20 to 1111. Really strange, value got updated but addresses are similar as that in Step-1, whereas addresses were different in earlier example of value type int. Similar address indicates that it updates data in actual copy and does not create new copy.
Refer step -3:
After executing the UpdateValue method let's check the value and address again. Strange, it is with updated value. Why value updated this time?
Answer -
It is because of "reference type" nature of int array.
Please Note:
Without “Unsafe” keyword you'll not be able to work with pointer in C#. Additionally, you need to do following settings only then your code will build else you will get error.
Please do the following setting to build the code.
- Right click on project solution and select properties.
- Select build option as shown below.
- Last but not least check the checkbox "Allow unsafe code".
- Thats it, save and try to build, it will defiantly build successfully.
I hope in this article you have cleared your doubts regarding working with value types/reference type. If you have any question /suggestions, then feel free to post in comments. For more information on pointers in C# you can refer Microsoft learn.
Are you willing to check more on C# then please visit HERE
String is Reference Type or Value Type
In this article we’ll discuss whether string is reference type or value type. Most of the time this question is asked in interview. String is reference type but always behave as value type. I have following sample code in which I am assigning some text to “name” variable and then will try to change it using “nameChange(name)” function.
public static void Main(string[] args)
{
string name = "John Smith";
nameChange(name);
Console.WriteLine(name);
Console.Read();
}Now body of above method will be like
static void nameChange(String name)
{
name = "Rakesh Kumar";
}Please hold on and think, what will be output.
Does the name will change form “John Smith” to "Rakesh Kumar". If you are thinking 'YES' then you are wrong. Answer is 'NO', name will not change.
Output will be as:
Why this happened:
Although string is reference type but always behave as value type so new copy will be created inside the function and but it will not affect the actual copy created in the beginning.
Is there no way by which we can change the value, of course YES, we can use ref keyword.
Decorate your method’s parameter with out or ref keyword as
string name = "John Smith";
nameChange(ref name);
Console.WriteLine(name);
Console.Read();
//Now body of above method will be
static void nameChange(ref String name)
{
name = "Rakesh Kumar";
}
Now output will be as:
In next example we’ll discuss about Reference type:
I am taking an array of string type. I assign three values in it as you can see in below example
string[] arr1 = new string[] { "One", "Two", "Three","Four"};
ArrayChange(arr1);
Console.WriteLine(String.Format("{0},{1},{2},{3}", arr1[0], arr1[1], arr1[2],arr1[3]));
Console.Read();
/*
Now “ArrayChange” method will have following code in it. I'll change the value which is at index [1].
Does it will change? YES, it will change the value.
*/
static void ArrayChange(string[] arr1)
{
arr1[1] = "Rakesh";
}
This is simple demonstration for your understanding. For further deep understanding we will see more in next article that how the addresses/values are behaving. For more information on pointers in C# you can refer link HERE.






No comments:
Post a Comment