Recipe 16.5 Returning a Pointer to a Particular Element in an Array
Problem
You need to create
a method that accepts a pointer to an array, searches that array for
a particular element, and returns a pointer to the found element.
Solution
The FindInArray
method, shown here, returns a pointer to an element found in an
array:
public unsafe int* FindInArray(int* theArray, int arrayLength, int valueToFind)
{
for (int counter = 0; counter < arrayLength; counter++)
{
if (theArray[counter] == valueToFind)
{
return (&theArray[counter]);
}
}
return (null);
}
This method is strongly typed for arrays that contain integers. To
modify this method to use another type, change the
int* types to the pointer type of your choice.
Note that if no elements are found in the array, a
null pointer is returned.
The method that creates an array of integers and passes a pointer to
this array into the FindInArray method is shown
here:
public void TestFind( )
{
unsafe
{
int[] numericArr = new int[3] {2,4,6};
fixed(int* ptrArr = &numericArr[0])
{
int* foundItem = FindInArray(ptrArr, numericArr.Length, 4);
if (foundItem != null)
{
Console.WriteLine(*foundItem);
}
else
{
Console.WriteLine("Not Found");
}
}
}
}
Discussion
The FindInArray method accepts three parameters.
The first parameter, theArray, is a pointer to the
first element in the array that will be searched. The second
parameter, arrayLength, is the length of the
array, and the final parameter, valueToFind, is
the value we wish to find in the array theArray.
The second parameter, arrayLength, informs the
for loop when the last element is reached. We
cannot determine the length of an array from just a pointer to that
array, so this parameter is needed. Many unmanaged APIs that accept a
pointer to an array also require that the length of the array be
passed.
|
We could pass a pointer to any element in the array through the
theArray parameter, but in doing so, we calculate
the remaining length by subtracting the element location from the
length of the array and passing the result to the
arrayLength parameter.
|
|
The loop iterates over each element in the array and looks for the
element that has a value equal to the parameter
valueToFind. Once this element is found, a pointer
to it is returned to the caller. We could have returned the actual
value or the index value (Counter), but by
returning a pointer to the element, more flexibility is offered to
the calling method. A pointer can be dereferenced to get the value
pointed to or it can be manipulated to point to the next or previous
elements in the array using simple pointer arithmetic.
The FindInArray method could also be written as
follows:
public unsafe int* FindInArray(int* theArray, int arrayLength, int valueToFind)
{
for (int counter = 0; counter < arrayLength; counter++, theArray++)
{
if (*theArray == valueToFind)
{
return (theArray);
}
}
return (null);
}
This version of this method uses pointer arithmetic to obtain the
correct element in the array to be returned by this method.
Note that it is possible to return null from this
method even though the return value is a pointer to a primitive type.
If it were simply a primitive type and not a pointer to one, we could
not return null from this method.
|
Make sure you check for
null pointers on return when calling a method that
may return a null pointer. Proper exception
handling can also mitigate this.
|
|
See Also
See the "unsafe" keyword in the
MSDN documentation.
|