CS360 Midterm Exam #2. March 11, 2014. James S. Plank

Answers and Grading


Question 1: 12 Points

S starts out as "ABCDEFGHIJKLMNOPQRSTUVWXYZ". Let's draw s, x and y as ASCII art. We'll represent the NULL character with an asterisk.

ABCDEFGHIJKLMNOPQRSTUVWXYZ*;
^ ^    ^
s x    y

After strcpy(x, "01234567"), it will look as follows:

AB01234567*LMNOPQRSTUVWXYZ*;
^ ^    ^
s x    y

And then after strcat(y, "abcde"), it will look as follows:

AB01234567abcde*QRSTUVWXYZ*;
^ ^    ^         ^
s x    y        x+15

So, here are the answers:

Grading

Three points per line. To get full credit for line two, it had to equal line one minus the first two characters. To get full credit for line three, it had to equal line one minus the first seven characters, or line two minus the first five characters. I did give partial credit to some answers in lines one and four.


Question 2: 12 Points

S starts out as "01234567890123456789". Let's draw s, and s+12:

01234567890123456789*
^           ^
s          s+12

After memcpy(s+12, argv[1], strlen(argv[1])), it will look as follows. Note, the memcpy() command doesn't copy the null character, because it only copies three bytes:

012345678901abc56789*
^           ^
s          s+12

So, line 2 is "012345678901abc56789".

Let's draw ip+1 and ip+2 in the picture. Because ip points to integers, ip+1 is four bytes beyond s and ip:

012345678901abc56789*
^   ^   ^    
s  ip+1 ip+2       

The memcpy() command also copies three bytes, and it now includes the null character:

0123AB*78901abc56789*
^   ^   ^    
s  ip+1 ip+2       

So, printing s gets us "0123AB". When we print ip[2] in hex, it will print the hex corresponding to the characters '1', '0', '9', and '8' in that order, because integers are interpreted in little endian. '0' is 0x30, so the integer printed will be 0x31303938. Here are the answers:

Grading

Four points per line with some partial credit given.


Question 3: 12 Points

S once again starts out as "ABCDEFGHIJKLMNOPQRSTUVWXYZ". The size of XX is eight bytes, not six. I discuss that in lecture. Because integers have to be aligned, two bytes of padding are added to the struct. Here is the state of memory after the memcpy().

ABCDEFGHABCDEFGHQRSTUVWXYZ*;
^       ^
s      x+1

So the first printf() prints "ABCDEFGHABCDEFGHQRSTUVWXYZ".

The strcpy() doesn't do anything, but I wanted to make sure that the first 7 bytes equal "ABCDEFG" even if you messed up the first line. j is set to equal whatever "ABCD" equals (yes, I can calculate it, but it's really easier not to calculate it). When I increment x->c1, that sets the 'E' to an 'F', and incrementing x->c1, sets the 'F' to an 'G'. Incrementing x->i sets the 'A' to a 'B'. Here's memory:

BBCDFGG*ABCDEFGHQRSTUVWXYZ*;
^               
s          

So it prints out "BBCDFGG". Now, incrementing x->i by (1 << 8) increments the second 'B' byte by one. Similarly, incrementing x->i by (1 << 17) increments the 'C' byte by two. So, S is now "BCEDFGG".

Finally, we incremented i by (1 + (1 << 8) + (1 << 17)). In hexadecimal, that is 0x20101. So that is the last value printed out. Here's the answer:

Grading

Three points per part, again with partial credit given.


Question 4: 14 Points

Bit-shifting i right by 8 simply deletes the last two digits in hex: 0x123.

Bit-shifting j left by 2 turns (1111 0000 1111 0000 1111) into (11 1100 0011 1100 0011 1100). So the answer is 0x3c3c3c.

Doing the binary AND with i and j zeros out the digits where j is zero: 0x10305.

Doing the binary AND with i and j copies the i digits where j is zero, and otherwise sets them to 0xf: 0xf2f4f.

Doing the binary XOR with i and j again copies the i digits where j is zero, and negates the digits where j is 0xf. To negate, simply subtract from 15. So the answer is 0xe2c4a.

When you bit shift j by four, that's one digit to the left. So you are doing the OR of 0xf0f0f with 0xf0f0f0. The answer is 0xffffff.

Finally, bit-shifting i left by 12 digits adds three zeros to the hex: 0x12345000. Oring that with j gets you 0x123f5f0f.

So, here are the answers:

Grading

Two points per line, with partial credit given.


Question 5: 12 Points

For the first four lines, the address of x+i is 4i more than the address of x. So, the first four lines are:
i=0  x+i=0x100130     x[i]=0x10014c
i=1  x+i=0x100134     x[i]=0x100130
i=2  x+i=0x100138     x[i]=0x100130
i=3  x+i=0x10013c     x[i]=0x100150
Pointers are four bytes, so the address of j+i will equal the address of x+i. However, now we treat the value as a pointer and look it up. For example, j is 0x100130. *j is 0x10014c and **j is 0x0x100138.
i=0  j+i=0x100130    *j[i]=0x100138
i=1  j+i=0x100134    *j[i]=0x10014c
i=2  j+i=0x100138    *j[i]=0x10014c
i=3  j+i=0x10013c    *j[i]=0x100130
The next loops do more indirection. Here are the pointers and values:

i X j = *X *j **j
0 0x100130 0x10014c 0x100138 0x100130
1 0x10014c 0x100138 0x100130 0x10014c
2 0x100138 0x100130 0x10014c 0x100138
3 0x100130 0x10014c 0x100138 0x100130

So, here's the answer:

i=0    j=0x10014c     **j=0x100130
i=1    j=0x100138     **j=0x10014c
i=2    j=0x100130     **j=0x100138
i=3    j=0x10014c     **j=0x100130

Grading

0.75 points per answer. There was no partial credit. Because the exam printed "*j=0x%x", I gave full credit to printing *j in the last four lines rather than j.


Question 6: 12 Points

Here's what the first 20 bytes of memory look like at the end of the first loop.
0x4d5750    0x4d5761    'a' |'W' |'M' |'\0'
0x4d5754    0x4d6264    'd' |'b' |'M' |'\0'
0x4d5758    0x635764    'd' |'W' |'c' |'\0'
0x4d575c  0x644d5754    'T' |'W' |'M' |'d' 
0x4d5760    0x4d576c    'l' |'W' |'M' |'\0'
So, when you print the four strings, you get:

i=0  y+4*i=aWM
i=1  y+4*i=dbM
i=2  y+4*i=dWc
i=3  y+4*i=TWMdlWM