Removing Data from an Array
Certainly if you can add a data item to an array, you should be able to take one back out. The reality is that you do not commonly take out the data item, you just cover it up, and make the list shorter. Consider the following pseudo code.
get the list length
identify the location of the value to be removed
begin a loop
- assign the item at the location above to the present location
(i.e., the one to be deleted)
- repeat the loop until the last item is assigned down one location
reduce the list length value by one
This algorithm again challenges you to use your looping actions effectively, and carefully so you don't lose data. The following code implements the action specified in the pseudo code.
int listArray[ MAX_VALUES ] = { 4, 9, 16, 25, 36, 49, 64, 81, 100 };
int listLength = 9;
int indexToBeRemoved = 6;
int index = indexToBeRemoved;
while( index < listLength - 1 )
{
listArray[ index ] = listArray[ index + 1 ];
index++;
}
listLength--;
Note that the listLength could have strategically been decremented prior to the loop so you could leave out the -1 in the loop condition to continue. Here is the removal process, starting with the initialized array. Remember that this array has a capacity of MAX_VALUES, so the values above the ninth element (i.e., location eight) are undefined (i.e., garbage). For example, if MAX_VALUES were 100, there would be 91 remaining elements, most likely holding garbage values.
At the beginning, index is six, and listLength is nine. Since index (6) is less than listLength – 1 (8), the loop will be implemented. The value at listArray[ index ] will be assigned the value at listArray[ index + 1 ], with the following result.
Next, index is incremented by one, so it is now seven (7).
At the beginning of the next loop iteration, since index (7) is less than listLength – 1 (8), the loop will be continued. The value at listArray[ index ] will be assigned the value at listArray[ index + 1 ], with the following result.
Next, index is incremented by one, so it is now eight.
At the beginning of the next loop iteration, since index (8) is not less than listLength - 1 (8), the loop is not implemented.
The next line of code decrements the value listLength from nine down to eight, and the process is completed.
There are two items to review here. The first is obvious. Notice that the value 100 is still left in the ninth element (i.e., index eight). There really is no way to "erase" data in the list. You could place a zero there, but there is little value in that. You have eliminated that value from view by reducing the listLength down so that the program will not attempt to access any values above location index seven (i.e., the eighth element).
The second issue is less obvious, but you should have noticed it by now. Consider the loop portion of the code again.
while( index < listLength - 1 )
{
listArray[ index ] = listArray[ index + 1 ];
index++;
}
Notice that index is set to increase until it gets to "less than" listLength - 1. This means that index will stop at a value of two below listLength. Think about this, and watch it very carefully. First, as mentioned previously, you should never attempt to access the value at the listLength element; this element is always above the usable values in the array. Remember that the highest element will be one value less than listLength because your array is zero-based. So, for a listLength of nine, your highest element will have a location or index of eight. This accounts for the use of the "less than" operator for the loop operation.
The next consideration is that you will be "reaching" above the present location to assign the value of the next higher array element to the present element. This means that if your index actually went to the ninth element (i.e., location eight), and you assigned the value from location index + 1 (i.e., location nine), you would be placing garbage into your list. This is why the while test is for "less than listLength - 1".
Watch this video to see the removal process occur in an animated way.
The removal process used for arrays here is simple but powerful. However, you must keep track of which values you are accessing in the array so you do not reach outside your array and place garbage into your list.
When creating a loop like this, you are strongly urged to write it out in pseudo code so that you will not go outside the appropriate array locations. Being off by one value is called an OBOB ("Off By One Bug"), but that is not the only problem. There are times that if you write data to the array in an inappropriate location, you will have the potential to overwrite other memory, a condition called being outside the array bounds, or boundaries. This frequently leads to computer program fails.
Later, when you start using arrays that are managed in classes, you will not have any trouble with this issue because they do not allow you to access inappropriate locations. However, there is a real danger of causing problems with fundamental C arrays. The final comment on this is that the danger is directly related to your programming skills. If you pseudo code and plan your loops, and make sure you are not "reaching" out to areas in memory where you do not belong, the above problems will not be an issue.
Once again, the processes of deleting data from arrays is not particularly difficult. However, like any other part of your programming, you must watch the limits of your loops carefully, and be very aware of which array elements you actually want to access or manipulate. The value of pseudo coding and good design cannot be overemphasized, and the need for testing your loop limits is absolute.
As you learn about lists of five, or nine, or fifty, remember that your goal is to work with lists of N items. Using N as an abstraction for "any number" of items, it will be easy for you to manage lists of any size. Once you have applied these tools to your programming, you can be a power user of C arrays. Also know that when you put arrays in classes and manage them, the process becomes easier and safer. That is coming soon . . .