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.

graphics/29fig06.gif

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 


From Java to C#. A Developers Guide
From Java to C#: A Developers Guide
ISBN: 0321136225
EAN: 2147483647
Year: 2003
Pages: 221
Authors: Heng Ngee Mok

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net