29.12. Pointer arithmetic

You can perform pointer arithmetic in an unsafe context. Let's discuss the + and – binary operators when applied to pointers.

Adding a number n to a pointer will increment it by (n*y), where y is the size of the pointer's referent type in number of bytes. For example, if you are dealing with double pointers, adding 3 to the pointer will increase its value by 24 since the double type takes up eight bytes of space.

Study the example below:

 1: using System;
 2:
 3: public class TestClass{
 4:
 5:   public unsafe static void Main(){
 6:     int a = 100;
 7:     int b = 101;
 8:     int c = 102;
 9:     int d = 103;
10:
11:     Console.WriteLine("Addr of a :"+(int)&a);
12:     Console.WriteLine("Addr of b :"+(int)&b);
13:     Console.WriteLine("Addr of c :"+(int)&c);
14:     Console.WriteLine("Addr of d :"+(int)&d);
15:     Console.WriteLine(""); // newline
16:
17:     int* pInt = &d;
18:     Console.WriteLine("pInt is pointing to :"+(int)pInt);
19:     Console.WriteLine("value stored there:"+(int)*pInt);
20:     Console.WriteLine(""); // newline
21:
22:     pInt += 1;
23:     Console.WriteLine("pInt is pointing to :"+(int)pInt);
24:     Console.WriteLine("value stored there:"+(int)*pInt);
25:     Console.WriteLine(""); // newline
26:
27:     pInt += 1;
28:     Console.WriteLine("pInt is pointing to :"+(int)pInt);
29:     Console.WriteLine("value stored there:"+(int)*pInt);
30:     Console.WriteLine(""); // newline
31:
32:     pInt += 1;
33:     Console.WriteLine("pInt is pointing to :"+(int)pInt);
34:     Console.WriteLine("value stored there:"+(int)*pInt);
35:  }
36: }

Output:

c:expt>test
Addr of a :1243332
Addr of b :1243328
Addr of c :1243324
Addr of d :1243320

pInt is pointing to :1243320
value stored there:103

pInt is pointing to :1243324
value stored there:102

pInt is pointing to :1243328
value stored there:101

pInt is pointing to :1243332
value stored there:100

The memory map after line 14 is executed is shown in Figure 29.6.

Figure 29.6. The result of pointer arithmetic.


On line 17, pInt is assigned the address of d (124320 10). When 1 is added to it (on line 22), instead of becoming 124321, pInt's new value becomes 124324 – and that's where c is storing its int value. You should be able to work out the logic behind the rest of the output based on this knowledge.

From this, it can be concluded that pointer additions and subtractions take place in 'chunks' of number of bytes depending on the pointer's referent type. You can also use the ++, , +=, and -= operators to move pointers about. Note that you can easily move your pointer 'out of bounds' to any desired address. Remember that resetting the value stored at random addresses results in unpredictable effects, especially if the value stored there is eventually used for other operations.

You can 'deduct' a pointer from another of the same type using the binary subtraction operator -. For example, if both pIntA and pIntB are pointers of type int*, the following statement is valid:

long difference = pIntA – pIntB;

However the difference between two pointers does not give the number of bytes in between the two addresses they store. It gives the number of bytes divided by the size of their referent type (in number of bytes). The difference operation always returns a long result. In the statement above, (pIntA-pIntB) will return the actual 'distance' between the two addresses they store, divided by 4 (the size of an int). You can only perform a difference between two pointers of the same type.

Here is an example:

 1: using System;
 2:
 3: public class TestClass{
 4:
 5:   public unsafe static void Main(){
 6:     int a = 100;
 7:     int b = 101;
 8:     int c = 102;
 9:     int d = 103;
10:
11:     Console.WriteLine("Addr of a :"+(int)&a);
12:     Console.WriteLine("Addr of b :"+(int)&b);
13:     Console.WriteLine("Addr of c :"+(int)&c);
14:     Console.WriteLine("Addr of d :"+(int)&d);
15:
16:     int* pIntA = &a;
17:     int* pIntB = &b;
18:     int* pIntC = &c;
19:     int* pIntD = &d;
20:
21:     Console.WriteLine(pIntA-pIntB); // 1
22:     Console.WriteLine(pIntA-pIntC); // 2
23:     Console.WriteLine(pIntA-pIntD); // 3
24:   }
25: }

Output:

c:expt>test
Addr of a :1243332
Addr of b :1243328
Addr of c :1243324
Addr of d :1243320
1
2
3

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.174.18