Professional C__ - Marc Gregoire [370]
Arrays Are Pointers!
A heap-based array is not the only place where you can use a pointer to refer to an array. You can also use the pointer syntax to access elements of a stack-based array. The address of an array is really the address of the 0th element. The compiler knows that when you refer to an array in its entirety by its variable name, you are really referring to the address of the 0th element. In this way, the pointer works just like a heap-based array. The following code creates an array on the stack, but uses a pointer to access the array:
int main()
{
int myIntArray[10];
int* myIntPtr = myIntArray;
// Access the array through the pointer.
myIntPtr[4] = 5;
}
The ability to refer to a stack-based array through a pointer is useful when passing arrays into functions. The following function accepts an array of integers as a pointer. Note that the caller will need to explicitly pass in the size of the array because the pointer implies nothing about size. In fact, C++ arrays of any form, pointer or not, have no built-in notion of size.
void doubleInts(int* theArray, size_t inSize)
{
for (size_t i = 0; i < inSize; i++) {
theArray[i] *= 2;
}
}
Code snippet from ArraysAndPointers\ArraysAndPointers.cpp
The caller of this function can pass a stack-based or heap-based array. In the case of a heap-based array, the pointer already exists and is simply passed by value into the function. In the case of a stack-based array, the caller can pass the array variable, and the compiler will automatically treat the array variable as a pointer to the array, or you can explicitly pass the address of the first element. All three forms are shown here:
size_t arrSize = 4;
int* heapArray = new int[arrSize];
heapArray[0] = 1;
heapArray[1] = 5;
heapArray[2] = 3;
heapArray[3] = 4;
doubleInts(heapArray, arrSize);
delete [] heapArray;
heapArray = nullptr;
int stackArray[] = {5, 7, 9, 11};
arrSize = sizeof(stackArray) / sizeof(stackArray[0]);
doubleInts(stackArray, arrSize);
doubleInts(&stackArray[0], arrSize);
Code snippet from ArraysAndPointers\ArraysAndPointers.cpp
Even if the function doesn’t explicitly have a parameter that is a pointer, the parameter-passing semantics of arrays are uncannily similar to that of pointers, because the compiler treats an array as a pointer when it is passed to a function. A function that takes an array as an argument and changes values inside the array is actually changing the original array, not a copy. Just like a pointer, passing an array effectively mimics pass-by-reference functionality because what you really pass to the function is the address of the original array, not a copy. The following implementation of doubleInts() changes the original array even though the parameter is an array, not a pointer:
void doubleInts(int theArray[], size_t inSize)
{
for (size_t i = 0; i < inSize; i++) {
theArray[i] *= 2;
}
}
Code snippet from ArraysAndPointers\ArraysAndPointers.cpp
You may be wondering why things work this way. Why doesn’t the compiler just copy the array when array syntax is used in the function definition? This is done for efficiency — it takes time to copy the elements of an array, and they potentially take up a lot of memory. By always passing a pointer, the compiler doesn’t need to include the code to copy the array.
To summarize, arrays declared using array syntax can be accessed through a pointer. When an array is passed to a function, it is always passed as a pointer.
Not All Pointers Are Arrays!
Since the compiler lets you pass in an array where a pointer is expected, as in the doubleInts() function shown earlier, you may be lead to believe that pointers and arrays are the same. In fact there are subtle, but important,