class Test { static int x; int y; unsafe static void F(int* p) { *p = 1; } static void Main() { Test t = new Test(); int[] a = new int[10]; unsafe { fixed (int* p = &x) F(p); fixed (int* p = &t.y) F(p); fixed (int* p = &a[0]) F(p); fixed (int* p = a) F(p); } } }demonstrates several uses of the fixed statement. The first statement fixes and obtains the address of a static field, the second statement fixes and obtains the address of an instance field, and the third statement fixes and obtains the address of an array element. In each case it would have been an error to use the regular & operator since the variables are all classified as moveable variables. The third and fourth fixed statements in the example above produce identical results. In general, for an array instance a, specifying &a[0] in a fixed statement is the same as simply specifying a. Here's another example of the fixed statement, this time using string:
class Test { static string name = "xx"; unsafe static void F(char* p) { for (int i = 0; p[i] != '\0'; ++i) Console.WriteLine(p[i]); } static void Main() { unsafe { fixed (char* p = name) F(p); fixed (char* p = "xx") F(p); } } }end example] Paragraph 71 In an unsafe context array elements of single-dimensional arrays are stored in increasing index order, starting with index 0 and ending with index Length -1. 2 For multi-dimensional arrays, array elements are stored such that the indices of the rightmost dimension are increased first, then the next left dimension, and so on to the left. Paragraph 81 Within a fixed statement that obtains a pointer p to an array instance a, the pointer values ranging from p to p + a.Length -1 represent addresses of the elements in the array. 2 Likewise, the variables ranging from p[0] to p[a.Length -1] represent the actual array elements. 3 Given the way in which arrays are stored , we can treat an array of any dimension as though it were linear. [Example: For example.
using System; class Test { static void Main() { int[,,] a = new int[2,3,4]; unsafe { fixed (int* p = a) { for (int i = 0; i < a.Length; ++i) // treat as linear p[i] = i; } } for (int i = 0; i < 2; ++i) for (int j = 0; j < 3; ++j) { for (int k = 0; k < 4; ++k) Console.Write("[{0},{1},{2}] = {3,2} ", i, j, k, a[i,j,k]); Console.WriteLine(); } } }which produces the output:
[0,0,0] = 0 [0,0,1] = 1 [0,0,2] = 2 [0,0,3] = 3 [0,1,0] = 4 [0,1,1] = 5 [0,1,2] = 6 [0,1,3] = 7 [0,2,0] = 8 [0,2,1] = 9 [0,2,2] = 10 [0,2,3] = 11 [1,0,0] = 12 [1,0,1] = 13 [1,0,2] = 14 [1,0,3] = 15 [1,1,0] = 16 [1,1,1] = 17 [1,1,2] = 18 [1,1,3] = 19 [1,2,0] = 20 [1,2,1] = 21 [1,2,2] = 22 [1,2,3] = 23end example] [Example: In the example
class Test { unsafe static void Fill(int* p, int count, int value) { for (; count != 0; count--) *p++ = value; } static void Main() { int[] a = new int[100]; unsafe { fixed (int* p = a) Fill(p, 100, -1); } } }a fixed statement is used to fix an array so its address can be passed to a method that takes a pointer. end example] Paragraph 91 A char* value produced by fixing a string instance always points to a null-terminated string. 2 Within a fixed statement that obtains a pointer p to a string instance s, the pointer values ranging from p to p + s.Length -1 represent addresses of the characters in the string, and the pointer value p + s.Length always points to a null character (the character with value '\0'). Paragraph 101 Modifying objects of managed type through fixed pointers can result in undefined behavior. [Note: For example, because strings are immutable, it is the programmer's responsibility to ensure that the characters referenced by a pointer to a fixed string are not modified. end note] [Note: The automatic null-termination of strings is particularly convenient when calling external APIs that expect "C-style" strings. Note, however, that a string instance is permitted to contain null characters. If such null characters are present, the string will appear truncated when treated as a null-terminated char*. end note]
| |
Jagger Software Ltd | |
Company # 4070126 | |
VAT # 762 5213 42 |