By the time you have completed this lab, you should be able to
*
, &
,
new
and delete
Choose who will be the first pilot, based on an attempt to maximize this lab's learning potential for both of you. If your assigned partner is more than 5 minutes late, ask the TA to pair you with someone else for this week.
This lab's first pilot should log in, create ~/cs16/lab07/ and make that your current directory.
Start ch. Then declare i as int, ip as pointer to int, d as a double array of size 3, and dp as pointer to double. Do not intitialize any of them:
ch> int i, *ip; ch> double d[3], *dp;
Assign the address of i to ip. Then assign the address of the first element of d (i.e., the name d itself) to dp. And finally, use the ch stackvar command to find out the "state" of your memory area so far (don't worry if your values of ip and dp differ from this example):
ch> ip = &i; 0x9f0f49c ch> dp = d; 0x9f14770 ch> stackvar i 0 ip 0x9f0f49c d (C array) 0.0000 0.0000 0.0000 dp 0x9f14770
Next set the value of i by using ip, and set the values of d using dp. Type all of the following assignment statements, and then use stackvar to verify i and d are set:
ch> *ip = 17; 17 ch> *dp = 1.25; 1.2500 ch> *(dp+1) = 2.5; // notice pointer arithmetic 2.5000 ch> dp[2] = 3.75; // notice pointer used like array name 3.7500 ch> stackvar i 17 ip 0x9f0f49c d (C array) 1.2500 2.5000 3.7500 dp 0x9f14770
You might be wondering what good are pointers if you already have a variable name you can use more easily. And you are right to wonder about that, because these simple examples are just for instruction, and do not have any programming value in practice. However, there are things we only do with pointers. In later parts of this lab you will learn some ways they are useful as function parameters, but first learn about how pointers can be used to access dynamically allocated memory.
The C++ operator new
dynamically allocates new memory - outside of
your program's static memory space - and returns a pointer to the
first byte in a consecutive block of memory that is large enough to hold the
type we request. So for example, the following statement acquires enough new
memory to store a double value, and saves the pointer to it in dp:
ch> dp = new double; 0x8e0a890
Even better, you can allocate lots of space dynamically, and use the
returned pointer as if it were the name of an array! Always
free dynamically allocated memory when you are done with it using
the delete
operator. Here we do that for the memory we just
allocated, and then we get new memory large enough to hold 10 doubles:
ch> delete dp; ch> dp = new double[10]; 0x8e0aeb0
Now perform the following steps in order:
Beware: sometimes ch will not behave properly when new or delete are used - yes, it seems that ch has a bug. If ch responds to the following code by continuously looping error messages, then close the terminal window. One time you might try to reopen the terminal, restart ch, and retry this lab step - but if it still doesn't work, then skip to Step 3 below. Good luck! |
ch> double *p; ch> for (p = dp+1; p < dp+10; p++) *p = CENSORED;
Before going to Step 3, make sure you succeeded by typing the following loop and verifying your results match:
ch> for (p = dp; p < dp+10; p++) cout << *p << endl; 10.0000 100.0000 1000.0000 10000.0000 100000.0000 1000000.0000 10000000.0000 100000000.0000 1000000000.0000 10000000000.0000
Free the dynamically allocated memory before proceeding to Step 3, but be careful
to include the []
, because dp now points to an array:
ch> delete [] dp;
First: switch roles between pilot and navigator if you did not already do that.
Download a copy of this useless version of a function that tries to swap two integers, intswap.chf, and store it by that name in your lab07 directory.
Read the function, and see how it successfully swaps the values stored in a and b: when done, a is set to the value b used to be, and b is set to the old value of a. But then try to use it. Start ch (if necessary), create two integer variables named anything you want (our example uses a and b only to emphasize a point), pass these two variables to intswap, and then type their names to let ch display their resulting values:
ch> int a = 17, b = -4; ch> intswap(a, b); ch> a 17 ch> b -4
Oops. It doesn't work. That's because it processed copies of the variables passed to it, and so it was not able to change the values of the original variables. C++ has reference variables that let you change the values of arguments passed to functions, but in the C language it is only possible to do that if the function has pointers to the original variables. We want you to rewrite the function to operate on pointers, and it means the addresses of the two variables must be passed to the function when we use it. Here are the steps to take and the results to expect:
ch> emacs intswap.chf ch> remvar intswap ch> intswap(&a, &b); ch> a -4 ch> b 17
Things to notice: (1) ch's remvar command is used to remove the old version of intswap from memory, so ch will load the edited version when it is used - this step means we don't have to exit ch to use the newer version; (2) addresses of a and b are passed to intswap; and (3) it works now!
Open intswap.chf in an editor, and make the following changes:
Save the file and exit the editor. Then test the function with ch (after removing the previous version if you did not exit ch yet).
Beware "segmentation faults" that might shut down ch. Read the error
messages, and try to fix the problem before asking a TA for help. Also,
when you're done with this lab, use rm
to delete any
files beginning with "core" that might have been created in your
current directory.
Exit ch when you are done testing the function. We will use swaptest.cpp to test it when you submit (notice it #includes "intswap.chf" to do that) - read it to know how useful your function is.
If you are still logged on, and your current directory is still the same as your function, then the quickest way to submit is by entering the following command (suggest you copy/paste):
~submit/submit -p 965 intswap.chfOtherwise you can use the submit.cs interface at https://submit.cs.ucsb.edu/ from your web browser - submit intswap.chf for Lab07. A perfect score is 50/50 points.
If you are working with a partner, be sure that both partners' names are in a comment at the top of the source code file, and be sure to properly form a group for this project in the submit.cs system.
Each student must accomplish the following to earn full credit [50 total points] for this lab:
The deadline for submitting your work for credit is tonight by 11:59 pm.
Optional Extra Challenge
- Very small revisions to your modified intswap function can make it work to swap pointers. First copy intswap.chf to intptrswap.chf, and edit the new file to make it work as follows (continuing the ch session from Step 3):
ch> int *pa = &a, *pb = &b; ch> *pa -4 ch> *pb 17 ch> intptrswap(&pa, &pb); ch> *pa 17 ch> *pb -4 ch> a -4 ch> b 17As the last two lines show, only the pointers are swapped - now pa points to b, and pb points to a - but the values at a and b are not swapped. Hint: just change all type declarations.- Some of you got used to the Python range function that produced a sequence of values ranging from a specified start value to just less than a specified end value, at steps of a specified amount. For example, range(4, 12, 2) produces the sequence {4, 6, 8, 10}. Now that you know how to allocate memory dynamically, you should be able to write a function named range that takes 3 parameters and returns a pointer to a section of memory that contains the sequence specified by the parameters. PLAN such a function.
- Implement and test the range function you planned in the last challenge. Name the file range.chf to test it in ch. Beware segmentation faults and other mishaps though - you might even have to exit your session altogether to regain control. Another hint: the number of values in the sequence will be no more than
1+(end-start)/step
. Here's how ours works:ch> int *r = range(10, 27, 5); ch> int i; ch> for (i=0; i<4; i++) cout << r[i] << endl; 10 15 20 25 ch> delete [] r;Remember to free the dynamically allocated memory when you are done with it!
Prepared by Michael Costanzo.