What's the matter with pointers?
Monday, 25 October 2010
Article Index
What's the matter with pointers?
Inherent dangers
Multiple indirection
Pointers to structs

 

Banner

Multiple indirection

If you think you have got the idea of indirection then it’s time to put you to the test. The real mark of a pointer expert is being able to handle double, treble and more… indirection. In theory this is easy.

For example,

int** ppMyInt;
int* pMyInt;
int MyInt=1234;
pMyInt = &MyInt;
ppMyInt = &pMyInt;
MessageBox.Show((**ppMyInt).ToString());

In this case we declare a pointer to a pointer, i.e. ppMyInt and use it to point at pMyInt. To display the value pointed at by pMyInt, i.e. the value in MyInt, we have to use two levels of indirection as in **ppMyInt. In this case double indirection is fairly easy to follow but in real cases it can become very difficult to work out when you need a pointer or a pointer to a pointer and so on.

Pointers, arrays and fixed

There is a very close relationship between pointers and arrays, indeed you could say that pointers in languages such as C and C++ were introduced just so that it was possible to create arrays.

In principle the address of the first element of an array can be used to find any element of an array but things are a little more complicated. For example,

int[] MyArray = new int[10];
for (int i = 0; i < 10; i++) MyArray[i] = i;
int* pMyArray = &MyArray[0];
MessageBox.Show((*pMyArray).ToString());

This should create a pointer to the first element of the array but if you try it you will discover that you simply get an error to the effect that you can’t take the address of an unfixed expression.

The reason is that while MyArray[0] is just an integer variable the compiler knows that the array is a managed object and can be moved at any time. If you were to take the address of an array and then it moved the address would be useless.

To take a meaningful array address you have to use the fixed keyword:

fixed(pointer declaration)
{
instructions to be carried
out while data is fixed
}

For example:

fixed (int* pMyArray= &MyArray[0])
{
MessageBox.Show((*pMyArray).ToString());
}

will work and display the contents of the first element of the array. You can also use the array name as a shorthand for &MyArray[0] as in:

fixed (int* pMyArray= MyArray)
{
MessageBox.Show((*pMyArray).ToString());
}

Notice that the pointer declared in the fixed statement goes out of scope when it ends so you can’t use pMyArray unless the array is fixed.

If you want to access other array elements then you simply use pointer arithmetic as in:

fixed (int* pMyArray= MyArray)
{
MessageBox.Show((*pMyArray+5).ToString());
}

which displays MyArray[5].

Notice that this is rather more subtle than you might think as adding 5 to the address of the start of the array actually adds 5 times the size of a single integer element.

That is, the arithmetic operators have been overloaded to add units in the size of the data type being pointed to. There is a sizeof operator which returns the size of any value type and this is used to work out what to add to a pointer.

That is, pointer+5 is translated to

pointer+5*sizeof(pointertype);
To complete the connection between arrays and pointers you can also use array indexing as a shortcut to dereferencing and pointer arithmetic. That is pointer[5] is a synonym for *pointer+5:
fixed (int* pMyArray = &MyArray[0])
{
MessageBox.Show(pMyArray[5].ToString());
}

There is a restriction on the use of the fixed pointer in that it cannot be modified within the fixed statement. This isn’t a problem as you can simply make a copy of it:

fixed (int* pMyArray= MyArray)
{
int* ptemp = pMyArray;
MessageBox.Show((*++ptemp).ToString());
}

which displays the contents of MyArray[1].

This sort of pointer manipulator works with multidimensional arrays. For example:

int[,] MyArray = new int[10,10];
fixed (int* pMyArray= &MyArray[0,0])
{
for (int i = 0; i < 100; i++)
{
*(pMyArray + i) = i;
}
}

This initialises a two-dimensional array by accessing it as a linear block of memory. Of course, the order in which the array is initialised depends on how it is stored in memory and I leave it to you to breakpoint the example and discover if it is stored in row or column order. It is this sort of trick, i.e. accessing a 2D array as if it was a 1D structure, that made, and still makes to some, pointers so attractive.

Notice that you can initialise multiple pointers within a fixed statement as long as they are all of the same type. To initialise multiple pointers of different types you have to use nested fixed statements one for each type.

<ASIN:0470495995>

<ASIN:0672330792>

<ASIN:1430229799>

<ASIN:0262201755>

Banner



Last Updated ( Monday, 25 October 2010 )
 
 

   
RSS feed of all content
I Programmer - full contents
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.