static unsafe void ArrayAndString_Test() { int[] arr = { 1, 2, 3, 4, 5 }; string s = "test"; //无法获取托管类型(P)的地址和大小,或声明指向它的指针 //&arr; //&arr[0]; //&s; fixed(int *p = &arr[0]) { Print.Address((long)p); } fixed(int *p = arr) { Print.Address((long)p); } fixed(char *p = s) { Print.Address((long)p); } }
static unsafe void Main(string[] args) { //Console.WriteLine(nameof(StackOverflow_Test)); //StackOverflow_Test(); unsafe { int *a = stackalloc int[10]; Print.Address((long)a); } Span <int> aa = stackalloc int[10]; unsafe { fixed(int *p = aa) { Print.Address((long)p); } } Console.WriteLine(); Span_Test(); Console.WriteLine(); Console.WriteLine(nameof(StructAlloc_Test)); StructAlloc_Test(); }
static unsafe void StructAlloc_Test() { var n = sizeof(A <int>); Console.WriteLine(n); Span <A <int> > arr = stackalloc A <int>[] { new A <int>() { X = 1, Y = 1 }, new A <int>() { X = 2, Y = 2 }, new A <int>() { X = 3, Y = 3 } }; fixed(A <int> *p = arr) { var p1 = p + 1; Print.Address((long)p); Print.Address((long)p1); Console.WriteLine(p1->X); } }
static unsafe void Main(string[] args) { var obj = new P(); //无法获取托管类型(P)的地址和大小,或声明指向它的指针 //fixed (int* p = &obj) //{ //} fixed(int *p = &obj.x) { *p = 1; //p++; //p是只读的,不能修改 int *p2 = p; p2++; *p2 = 10;//y=10 Print.Address((long)p); } fixed(PP *p = &obj.pp) { p->x = 1; p->y = 2; (*p).x = 1; (*p).y = 2; Print.Address((long)p); } fixed(int *xp = &obj.pp.x, yp = &obj.pp.y) { Print.Address((long)xp); Print.Address((long)yp); } Console.WriteLine(obj.x); Console.WriteLine(obj.y); Console.WriteLine(); Console.WriteLine(nameof(ArrayAndString_Test)); ArrayAndString_Test(); Console.WriteLine(); Console.WriteLine(nameof(Span_Test)); Span_Test(); Console.WriteLine(); Console.WriteLine(nameof(FixedSizeBuffers_Test)); FixedSizeBuffers_Test(); }
static unsafe void StackOverflow_Test() { const int len = 1024;//1k //run on my computer, the max stack size 1494k, more than will throw StackOverflowException const int max = 1494; while (i < max) { i++; var a = stackalloc byte[len]; Console.WriteLine(i); Print.Address((long)a); } }
static unsafe void Index_Test() { Index i1 = 0; // number 3 from beginning Index i2 = ^ 4; // number 4 from end int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; fixed(int *p = a, pp = &a[i1]) { Print.Address((long)p); Print.Address((long)pp); } Console.WriteLine($"{a[i1]}, {a[i2]}"); // "3, 6" }
static unsafe void FixedSizeBuffers_Test() { var a1 = new SB() { arr = new int[5] }; var a2 = new FSB(); Print.Address((long)&a2); Print.Address((long)a2.arr); Print.Address((long)&a2.arr);//数组指针变量的地址 Print.Address((long)&a2.x); //Console.WriteLine(sizeof(SB));//SB作为托管类型不能计算大小 Console.WriteLine(sizeof(FSB)); }
static unsafe void Span_Test() { var a = stackalloc byte[8]; Print.Address((long)a); Print.Address((long)(a + 4)); Span <int> span = new Span <int>(a, 2); span[0] = 1; span[1] = 2; fixed(int *p = span) { Print.Address((long)p); var pp = p; Print.Address((long)(pp + 1)); Print.Address((long)(pp + 2)); } }
static void ManagedHeap_Test() { var arr = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; var span = new Span <int>(arr); foreach (var s in span) { Console.WriteLine(s); } unsafe { fixed(int *p = arr, pp = span) { Print.Address((long)p); Print.Address((long)pp); } } }
static unsafe void Range_Test() { Range r = new Range(Index.Start, Index.End);//等价于 0..^0 int[] a = { 0, 1, 2, 3 }; var aa = a[r]; Span <int> s = a[r]; a[0] = 10; fixed(int *p = a, pp = aa, ps = s) { Print.Address((long)p); Print.Address((long)pp); Print.Address((long)ps); } foreach (var i in aa) { Console.WriteLine(i); } }
static void Stack_Test() { Span <int> span = stackalloc int[5]; //span[5] = 10;//throw System.IndexOutOfRangeException unsafe { //stack 由高地址向低地址分配空间 var i = stackalloc int[1]; var arr = stackalloc int[4]; var span2 = new Span <int>((void *)arr, sizeof(int) * 5); fixed(int *p = span2, p5 = &span2[4]) { Print.Address((long)arr); Print.Address((long)i); Print.Address((long)p); Print.Address((long)p5); } } }