By the time you have completed this lab, you should be able to
This lab's first pilot should log in, create ~/cs16/lab09/ and make that your current directory.
void*
at the ch promptStart ch. Then declare x as an int, and initialize it to 10. Declare xp as an int*, and initialize it to the address of x. Declare vp as a void*, and initialize it to xp.
ch> int x = 10; ch> int* xp = &x; ch> void* vp = xp;
Enter here a thought exercise. Only 4 bits are needed to represent decimal 10 in binary, so it will fit into a single byte (8 bits). As such, a char would be large enough to store decimal 10. This is illustrated below:
ch> sizeof( int ) 4 ch> sizeof( char ) 1
We have a full three extra bytes in our data type (int) that are not required! This begs the question: in which of the four bytes of an int are the bits for decimal 10 stored? There are a number of ways to answer this question, but one way involves manipulating void pointers. Using void pointers, we can address individual bytes in an int as characters, and get the values of individual bytes of an int that way. This is shown below (with admittedly a bit of ugliness related to casting):
ch> (int)(*((char*)vp)) 10 ch> (int)(*((char*)vp + 1)) 0
Here, the first line does the following:
This is further confirmed by trying to look at more bytes of the integer, as with the second line. The second line does the same as the first, except it looks at the second byte of the integer. As shown, this is 0, indicating that the next byte of the integer contains only 0. This is consistent with the hypothesis that the bits for 10 are at the front of the integer and that integers grow from left to right. Intuitively, if drawing integers out by hand, this is like padding the front with zeros, as with 00010.
(As an aside, if you're interested to learn more about how integers can be represented internally, you should read this article on Wikipedia. The machines we are working on are all little-endian, by the way.)
You can exit ch now. Make a copy of this skeleton program in your (first pilot's) ~/cs16/lab09 directory.
You can cp
a copy from the instructor's account:
-bash-4.2$ cp ~kyledewey/cs16/lab09/megacopy.c ~/cs16/lab09/
Study the code and what it does.
As written, the code is complete, except for the all-important
megacopy
function.
This function should copy, byte-for-byte, the contents of src
to dest
.
It will copy size
bytes, as specified through the use of the
sizeof
operator in the main
function.
(Hint: Because you need to do a byte-for-byte copy, you will likely need to
cast the void
pointers to char
pointers, as a char
is only one byte long.)
The correct output for megacopy.c
is shown below:
-bash-4.2$ ch ./megacopy.c Sources: Foo.x: 5 Foo.y: 2.500000 Bar.string: bar string Bar.foo: Foo.x: 5 Foo.y: 2.500000 Destinations: Foo.x: 5 Foo.y: 2.500000 Bar.string: bar string Bar.foo: Foo.x: 5 Foo.y: 2.500000
The only code that may be modified is that for the megacopy
function.
First: switch roles between pilot and navigator if you did not already do that.
Make a copy of this skeleton program in your (first pilot's) ~/cs16/lab09 directory.
You can cp
a copy from the instructor's account:
-bash-4.2$ cp ~kyledewey/cs16/lab09/megacopyHeap.c ~/cs16/lab09/
This code is adapted directly from megacopy.c
.
The differences are that:
megacopy
function is now called the megacopyHeap
function.megacopyHeap
returns a void*
, which points to a newly-allocated block of memory.megacopyHeap
are free
d at the end of the main
function.This code should work exactly like the original megacopy.c
, except now the megacopyHeap
function should allocate size
bytes of memory and return the block of memory it allocated after copying over the contents of src
to it.
As a hint, you will have to use either malloc
or calloc
to allocate said block of memory.
Additionally, most of the code will remain the same between the original megacopy
function and the new megacopyHeap
function.
In fact, it is possible to implement megacopyHeap
in terms of megacopy
; the bulk of the work can be performed by megacopy
without modification.
In the instructor's solution, only two lines needed to be modified to arrive at a functional megacopyHeap
function.
The correct output for megacopyHeap.c
is the same as for megacopy.c
, as shown below:
-bash-4.2$ ch ./megacopyHeap.c Sources: Foo.x: 5 Foo.y: 2.500000 Bar.string: bar string Bar.foo: Foo.x: 5 Foo.y: 2.500000 Destinations: Foo.x: 5 Foo.y: 2.500000 Bar.string: bar string Bar.foo: Foo.x: 5 Foo.y: 2.500000
Submit your code with the
turnin
program. You MUST have both your name and your partner's name in the file in order to receive credit. Remember that the original pilot needs to do this step, since that is whose account you have been using in Cooper Lab.Bring up a terminal window on CSIL or the Cooper Lab, and cd into the original pilot's cs16 directory, and cd again into the lab09 directory. Then type the following to turn in the files from Steps 3 and 4 above:
turnin lab09@cs16 megacopy.c megacopyHeap.cRespond "yes" when the program asks if you want to turn in (be sure to read the list of files you are turning in), and then wait for the message indicating success.
It is strongly recommended that you remain for the whole lab and take this step seriously. We are here to help you understand, but we cannot do that unless you ask questions.
Look through any code and questions related to this course. Specifically, consider the following, prioritized by how relevant they are to Exam #3:
cp
from ~kyledewey/cs16/lab09/isumRecursive.c.cp
from ~kyledewey/cs16/lab09/phoneBook.c.megacopy.c
is saved, and it compiles and executes properly.megacopy.c
has been turned in.megacopyHeap.c
is saved, and it compiles and executes properly.megacopyHeap.c
has been turned in.Prepared by Kyle Dewey.