Consider the following code:
static void Main(string[] args)
{
int max = 1024;
var lst = new List<int>();
for (int i = 1; i <= max; i *= 2) { lst.Add(i); }
var arr = lst.ToArray();
IterateInt(arr);
Console.WriteLine();
IterateShort(arr);
Console.WriteLine();
IterateLong(arr);
}
static void IterateInt(int[] arr)
{
Console.WriteLine("Iterating as INT ({0})", sizeof(int));
Console.WriteLine();
unsafe
{
fixed (int* src = arr)
{
var ptr = (int*)src;
var len = arr.Length;
while (len > 0)
{
Console.WriteLine(*ptr);
ptr++;
len--;
}
}
}
}
static void IterateShort(int[] arr)
{
Console.WriteLine("Iterating as SHORT ({0})", sizeof(short));
Console.WriteLine();
unsafe
{
fixed (int* src = arr)
{
var ptr = (short*)src;
var len = arr.Length;
while (len > 0)
{
Console.WriteLine(*ptr);
ptr++;
len--;
}
}
}
}
static void IterateLong(int[] arr)
{
Console.WriteLine("Iterating as LONG ({0})", sizeof(long));
Console.WriteLine();
unsafe
{
fixed (int* src = arr)
{
var ptr = (long*)src;
var len = arr.Length;
while (len > 0)
{
Console.WriteLine(*ptr);
ptr++;
len--;
}
}
}
}
Now, by no means do I have a full understanding in this arena. Nor did I have any real expectations. I'm experimenting and trying to learn. However, based off what I've read thus far, I don't understand the results I got for short
and long
.
It is my understanding that the original int[]
, when read 1 location at a time (i.e. arr + i
), reads 4
bytes at a time because of the data types size and thus the value *ptr
is of course the integral value.
However, with short
I don't quite understand why every even iteration is 0
(or arguably odd iteration depending on your root reference). I mean I can see the pattern. Every time I iterate 4 bytes I get the real integral value in memory (just like iterating the int*
), but why 0
on every other result?
Then the long
iterations is even further outside my understanding; I don't even know what to say or assume there.
Results
Iterating as INT (4)
1
2
4
8
16
32
64
128
256
512
1024
Iterating as SHORT (2)
1
0
2
0
4
0
8
0
16
0
32
Iterating as LONG (8)
8589934593
34359738372
137438953488
549755813952
2199023255808
-9223372036854774784
96276819136
32088581144313929
30962698417340513
32370038935650407
23644233055928352
What is actually happening with the short
and long
iterations?
When you say
pointer[index]
it gives yousizeof(type)
bytes at locationpointer + index * sizeof(type)
. So by changing the type that you "iterate with" you change the stride.short
you read halves of the originalint
's. Small ints have all zeros in their upper half.long
you read twoint
's at the same time, forced into onelong
. Atptr[0]
you are reading, for example,(1L << 32 | 2L)
which is a big number.You are still using the original
Length
measured in int-units, though, which is a bug. In thelong
-case you are reading outside the bounds of the array, in theshort
case you are reading too little.