Lab 6: Pointers and Arrays
Contents
Description
The purpose of this lab will be to gain experience defining working with pointers and also introduce you to arrays. This lab will be a little different from previous labs in that you will be completing several parts, which include some programming as well as drawing out memory. You should get each part reviewed by the professor when you complete it.
(Back to top)Tasks
Follow each of the tasks below in order. Get each reviewed by the professor.
Task 1: Creating a pointer
Consider the following program:
Draw the memory out for this on a piece of paper. Assume that areaCode
is stored at memory address 1 and areaCodePointer
is stored at memory address 5. Now answer the following questions (you can write them down on a sheet of paper, or in Sublime):
- At the end of the program, what is the value of
areaCode
? - How about
areaCodePointer
? - How about
*areaCodePointer
? - How about
&areaCodePointer
? - How about
&areaCode
?
You can check your answers by using cout
statements. Go ahead and create 5 cout
statements, one to print out the value of each of the pieces of information sought above. Were your answers correct?
We can use pointers for more than just ints. Below your cout
lines, write code to:
- declare a string variable called
name
and assign it your name - create a string pointer called
namePointer
, and make it so that it points to the memory ofname
- change the value of
name
vianamePointer
to another name (just like we did withareaCodePointer
above) - use
cout
statements to check that*namePointer
andname
have the same value
Task 2: Allocating dynamic memory
We can set pointers to space allocated elsewhere in memory and not stored in conjunction with a regular variable. This is called dynamic memory. Recall that we allocate with the keyword new
and deallocate with the keyword delete
. Consider the following code:
Draw the memory out for this up to line 15 on a piece of paper. Assume that the variable zipCode
has address 1 and the allocated memory as address 500. The write down what the following values will be:
&zipCode
zipCode
*zipCode
Write two cout
statements to verify your answers just below line 16.
Below the line that deletes zipCode
, create a string pointer called name
and allocate memory for it. Then store your name in it, and print it out. Don't forget to add a line to deallocate the memory. Call the professor over to check your work.
Task 3: Passing pointers between functions
In this task, we will get some hands on experience passing pointers into functions, as well as returning them from functions. Take a look at the code below. It defines two functions: one that that takes an int
pointer as its only parameter and modifies the contents. The other takes a regular (static) int
as a parameter, then creates an int
pointer to new dynamic memory, then copies the input value to that new memory before finally return the pointer.
Now draw out the memory for the code in main
, including all function invocations. By the time the computer reaches line 22, what is the value pointed to by x
and y
? Add in cout
lines at line 22 to check it out.
Now create another function called copyString
that takes a string and makes a copy of it to dynamic memory. Invoke that function from main
.
Task 4: Static arrays
We haven't read about arrays yet, but they are quite convenient little things. Arrays are a way of storing a list of items. If we wanted to store five integers up until now, we would create five separate variables, one for each integer. However, arrays allow use to declare one variable and store a preset number of things in it. Here's how it works:
The code above demonstrates a couple of things. First, there are two ways to declare an array. On the left hand side of each, we see the type of the array (int
in this case), the name of the array, and then a pair of square brackets with the size or length of the array ([5]
in this case). What's on the right side differs.
In the first example, we have a combination declaration and initialization, and is great if we know what goes in the list. On the right hand side we have a pair of curly braces with each of the elements of the array separated by commas and in the order that we want them to appear in the list. We can only ever use curly braces like this if they are part of a declaration + initialization—we cannot break up the two and still use curly braces.
In the second example, we have the declaration with no right hand side. Then, on the line below. we start to assign a value to each element of the array. Let's consider the line 13: myIntArray2[0] = 1;
. This says: assign the integer 1 to the element at index 0 of our array. Now, let's stop right there. What's an index? An index is our way of referring to an element of an index. As strange as it may seem, indexes start at 0, not 1. So, myIntArray2[0]
is talking about the first element of the array. This looks similar to the declaration because of the square brackets, but it's not! The square brackets, when part of a declaration, signify the size of the array. When not part of a declaration, they are used to specify the index of the element to access. We can use myIntArray[0]
just like a variable—we can assign values to it, we can assign it to other variables, and we can use it in expressions (e.g., cout << myIntArray2[0];
.
Now, create an array of 5 strings!
Task 5: Dynamic arrays
In the long run, static arrays will hold us back—it turns out that we have to know their size at compile time. However, dynamic arrays are easy now that we know about pointers!
Dynamic arrays are arrays that we allocate memory for in the heap using the new
keyword. It's similar to what we did in Task 2, but slightly different:
First of all, our array, myArray
, is an int
pointer—just like before! But the memory it points to isn't just for an int, it's for three ints. We say this by using square brackets after the type when we allocate memory with the new
keyword: new int[3];
.
Next, we don't need a * to dereference our array—the square brackets are doing that for us automatically. So, myArray[0]
will access the first thing in the array, just like with a static array.
Finally, we cannot use the regular delete
keyword to deallocate our array. Rather, we need to use a special version: delete[]
. And that's it!
Array pointers can be passed just like regular pointers. In fact, they look just like regular pointers, except we access them like arrays. One thing that is typically necessary is to pass the size of the array around with the array. So if you have a function that takes an array, you should also have a parameter for its size. This way, you know how many things the array holds.
Actually, it turns out that static arrays and dynamic arrays can both be passed to functions the same way—using the pointer notation. This is because static arrays are very similar to pointers that point to static memory (they are not technically pointers, though). Kinda cool! See the example below.
Now convert your static string array from Task 5 to a dynamic string array.
(Back to top)