Arrays: Memory

Problems and Solutions 1

Problems and Solutions 2

We have seen that it is possible to initialize an array in its
declaration. For example a one dimensional array would be declared
as follows:

int arr[] = {1, 4, 5};

Now with a two dimensional array we would do something similar:

int arr[][3] = {
{1, 4, 5},
{2, 3, 6},
{4, 2, 5}
};

In a two-dimensional array all of the rows be the same number
of columns wide. For this reason, you must include a size between each
pair of brackets except the first, which is optional. If you look
at the syntax, what we are actually doing is declaring a one dimensional
array of one dimensional arrays.

Figure %: 2-D Array in Memory

Now we will cover why all of the columns need to be of the same width
when we explain what actually happens when you index into an array.
If it is a one dimensional array, the indexing step is simple.
It can be thought of through pointer arithmetic. To get arr[2] you
just dereference the pointer plus two: *(arr + 2). The process
gets more complicated when dealing with multi-dimensional arrays
because each of the dimensions will affect the
pointer arithmetic differently. Specifically, the index in the row position
should be multiplied by the column width. So arr2[2][1] is the same
as *(arr + 2 * 3 + 1) which is the pointer plus the row number times
the column width plus the column number. If the number of columns
were not fixed it would be impossible to do this sort of pointer
arithmetic to arrive at the correct cell. One way to think about this
is that a two dimensional array looks the same as a one dimensional
array in memory. It is just one chunk of memory. The column width is
necessary to know how to fold this chunk of memory into rows.

Another significant implication of arrays really just being a pointer
to a chunk of memory is that when you pass an array into a function,
the function can modify it and have those modifications affect the
array in the place that the function was called. In other words, there
is not local copy of the entire array passed into a function. The
reason for this is that only a pointer to the array gets passed in,
which means that when you assign to the array you are affecting the
same memory that the array from the calling function refers to. This
feature can be very useful for processing large amounts of data in
functions, but can also create some confusing bugs if you forget that
only a pointer to an array gets passed to functions.