unsafe
{
int x = 0;
int* pX = &x;
*pX = 13;
}
Point pt;
Point* pPt = &pt;
pPt->X = 13;
pPt->Y = 14;
pPt->Offset(1,2);
List<object> list = new List<object>();
//List<object>* pList = &list;//won't compile!
unsafe class MyUnsafeClass {...}
unsafe void MyUnsafeMethod() {...}
Speed Up Array Access
Scenario/Problem: | You
want direct access to an array for performance reasons and are willing
to forego .NET’s array-bounds checking and take responsibility for safe
behavior yourself. |
Solution: | By using pointers, you can speed up array lookups by an order of magnitude, but at the price of code safety and guarantees. |
This code shows that by using pointers you can gain direct access to memory, potentially overwriting data you didn’t mean to:
int size = 10;
int[] vals = new int[size];
try
{
for (int i = 0; i < size+1; i++)
{
vals[i] = i;
}
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine("Caught exception: " + ex.Message);
}
Console.WriteLine("Going out of bounds");
//prevent vals from moving in memory
fixed (int* pI = &vals[0])
{
//oops, going to far--overwriting memory we don't own!
for (int i = 0; i < size+1; i++)
{
pI[i] = i;
}
Console.WriteLine("No exception thrown! We just overwrote memory we shouldn't have!");
}
You can also use pointer arithmetic, just as you would in native languages:
fixed (int* pI = &vals[0])
{
int* pA = pI;
while (*pA < 8)
{
//increment 2 * sizeof(element)
pA += 2;
Console.WriteLine("*pA = {0}", *pA);
}
}
Note that adding one to a
pointer does not increase the memory address by 1 byte, but by 1
increment of the data type size, which in this example is an int, or 4 bytes.
Note
Most
programs do not need to use any of this pointer stuff, and it is quite
dangerous to do so, as evidenced by the “unsafe” status you have to
grant the code, in addition to the increased permissions required to run
programs that do this. If at all possible, try to create programs that
do not rely on these techniques.