CS360 Midterm Exam #1. January 31, 2019. James S. Plank

Answers and Grading

You can compile and run the first three programs yourself. Due to a deletion mishap, you can't compile the last two. The grading to this exam is two points per line of output. I gave some partial credit.

Question 1

At the point of the first printf() statements, here are k, cp and ip, viewed as chars and as ints:

Given that, the first four lines of output will be 0x3c, 0x78 0x3c2d1e0f and 0xb4a59687.

The memcpy() statement will move the four bytes starting at index 10 to the four bytes starting at index 2. When it's done, here are k, cp and ip, again viewed as chars and as ints:

The next four lines of output will therefore be: 0xb4, 0xc3 0xb4a51e0f and 0x7869d2c3.

When you increment cp by 12, it will have a pointer value that is twelve greater than k. The same is true of ip. Therefore, the difference between ip and k is 12 bytes, or three integers. It will print 3.

The difference between cp and (unsigned char *) k is 12, becuase both pointers point to bytes and their difference is 12.

The full output is therefore:

0: 0x3c
1: 0x78
2: 0x3c2d1e0f
3: 0xb4a59687
4: 0xb4
5: 0xc3
6: 0xb4a51e0f
7: 0x7869d2c3
8: 3
9: 12


Question 2

Answers and explanations:
0: 0x66e32000 -- This shifts off the leftmost three digits and shifts in three zeros.
1: 0x7f58     -- This shifts off the rightmost three digits and shifts in four zeros (not printed).
2: 0x6503002  -- The f's retain the digits of e, and the 0's clear them.
3: 0xc0060e30 -- Now the f's clear the digits of c, and the 0's retain them.
4: 0x7ff8fe9f -- The 0's retain the digits of d, and the f's turn into f's.
5: 0x7f585e9d -- XOR is associative and commutative, and c^c = 0, so this equals d.
6: 0x543e0000 -- This isolates the middle four digits, and then shifts them two to the left.
7: 0x26       -- This is the same as binary not.  d becomes 2, and 9 becomes 6.
8: 0x90       -- Since b is a char, the d is shifted off, and a zero is shifted in.
9: 0x4e0      -- Since g is an int, now both digits are shifted over, and a zero is shifted in.


Question 3

Here are b, x and y after the various commands. I'm going to use * to denote the null character:

                           012345678901234567890123456789012345678901234567890123456789 
b[59] = '\0';              AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA*
                           b   x     y

012345678901234567890123456789012345678901234567890123456789 strcpy(b, "Smith"); Smith*AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA* b x y
012345678901234567890123456789012345678901234567890123456789 strcat(b, "Pearson"); SmithPearson*AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA* b x y

First three lines:

0: SmithPearson
1: hPearson
2: on

                           012345678901234567890123456789012345678901234567890123456789 
strcpy(b,"Schema-Gallery") Schema-Gallery*AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA*
                           b   x     y

012345678901234567890123456789012345678901234567890123456789 strcpy(x, "Binky"); ScheBinky*lery*AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA* b x y

Next two lines:

3: ScheBinky
4: lery

                           012345678901234567890123456789012345678901234567890123456789 
strcat(y, "Tent");         ScheBinky*leryTent*AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA*
                           b   x     y

012345678901234567890123456789012345678901234567890123456789 strcat(y, "Fly"); ScheBinkyFly*yTent*AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA* b x y

Next two lines:

5: ScheBinkyFly
6: ly

                           012345678901234567890123456789012345678901234567890123456789 
After the for loop:        FrienFrienFrienFrienFrienFrienFrienFrienFrienFriend*AAAAAAA*
                           b   x     y

012345678901234567890123456789012345678901234567890123456789 strcpy(y, "Tater"); FrienFrienTater*rienFrienFrienFrienFrienFrienFriend*AAAAAAA* b x y
012345678901234567890123456789012345678901234567890123456789 strcpy(b+20, "Tot"); FrienFrienTater*rienTot*nFrienFrienFrienFrienFriend*AAAAAAA* b x y

Final three lines:

7: nFrienTater
8: ienTot
9: r


Question 4

Let's concentrate on the first three lines, which have to deal with x. This picture shows how the various indirections of x are calculated:

The first three lines:

0: 1985138680
1: 1985138684
2: 1985138700
This picture shows the various values and indirections involving e:

The next three lines:

3: 1985138696
4: 1985138704
5: 0x7652d010
This picture shows information for the next two lines. I've deleted the decimal because it's not necessary for the rest of the output:

6: 0x7652cff8
7: 0x7652cffc
Here's the picture for line 8:

8: 0x7652d000
You can calculate (e+12) by either adding 12*4 = 48 to e, or simply counting down twelve addresses on the diagram. The answer is:
9: 0x7652d010


Question 5

Variable x is of type (S1 *). The struct is 12 bytes (because you have to add three bytes of padding after b.

Variable y is of type (S2 *). The struct is 8 bytes (because you have to add three bytes of padding after b, so that y[1].i is aligned.

Variable z is of type (S3 *). The struct is 8 bytes, as there is no padding.

Here are answers and commentary:


0: B          -- x->b is four bytes after x, at 0x41696f44.  The character is B.
1: 2780278    -- x->i is at 0x41696f40 
2: BoiAx      -- After incrementing, x is 0x41696f4c, so x->s is a 0x41696f54 with a value of 0x41696f44.
3: 0x41696f5c -- Since x is 0x41696f4c, x+1 is 0x41696f58. &(x[1].b) is four bytes after that.
4: D          -- y+1 is 0x41696f48 and y+2 is 0x41696f50.  So &(y[2].b) is at 0x41696f54.
5: 1097428806 -- y+5 is 0x41696f68, so y[5].i is 1097428806.
6: 0x41696f4c -- From 4, y+1 is 0x41696f48, so &(y[1].b) is four bytes after that.
7: *          -- z->s is 0x41696f42.  The string that starts there is "*".
8: 1097428840 -- z+1 is 0x41696f48 and z+2 is 0x41696f50.  The int there is 1097428840.
9: iAx        -- z+3 is 0x41696f58.  So after doing z += 3, z->b is at 0x41696f5c, with a value of 0x41696f46