Question 1

As with the first midterm, let's proceed in pieces. What I like to do is annotate the memory with pointers and values. Here is the annotation for p and p[0] through p[4]. If you click on it, you'll get the full resolution picture:

The first loop prints out p[0] through p[4]. While those are pointers, we'll print them as integers; thus, they are the five decimal values starting at address 0x10013c:

1048936
1048956
1048908
1048904
1048900

For the next loop, we know that a points to the beginning of an array of (char *)'s. Thus, each pointer in memory from 0x100130 through 0x10013c points to the beginning of a string. Here's a picture:

Thus, the five strings begin at the following five locations

Therefore, the output is:

samson
dub
zak
geena
naomi

I should have made it extra credit to tell me from which video game these names come, and which name is missing. (Fuzion Frenzy, "jet").

The next loop treats the five values from the first loop as pointers to integers and prints their values. For example, p[0] equals 0x100168. Therefore *p[0] is 1852138855. Similarly, p[1] equals 0x10017c. Therefore *p[1] is 1836015982. Here's the annotated memory:

The output is:

1852138855
1836015982
1048900
1048904
1048908

For the next loop, we treat p[i] as pointing to an array of integers. Therefore, to print p[i][i], we count i integers down from p[i]:

i p[i] &p[i][i] p[i][i]
00x1001680x1001681852138855
10x10017c0x1001801952514153
20x10014c0x1001541677749871
30x1001480x1001541677749871
40x1001440x1001541677749871

Here is the annotated memory:

The output is:

1852138855
1952514153
1677749871
1677749871
1677749871

For the next loop, b starts at 0x10014c and we are going to loop until it is greater than or equal to 0x10017c. At each loop iteration, we move it forward by 4 integers (in other words, we add 16 to it). Here's how it looks in memory:

The output is:

1048900
1801550446
1852375137

Next, we start c at 0x10017c-10 = 0x100172. Here are the addresses and characters it prints:

Pictorally:

It prints "a!iIo".

Finaly, a[3] is 0x100168, so a[3][5] is the character at 0x10016d -- a Null character. We set it to 'b'. Memory looks as follows:

Then we copy "Jet" (plus NULL character) to 0x100170:

Thus, the print statement prints: "geenabinJet".

Here's the output (the program is in q1.c). Of course, if you run it, you'll get different pointers, but you should get similar output.

a: 0x100130
p: 0x10013c

1048936
1048956
1048908
1048904
1048900

samson
dub
zak
geena
naomi

1852138855
1836015982
1048900
1048904
1048908

1852138855
1952514153
1677749871
1677749871
1677749871

1048900
1801550446
1852375137

a!iIo

geenabinJet


Question 2

The variable a points to the top of an array of (char *)'s:

Thus, the first five lines print the values in 0xbfffddcc through 0xbfffdddf:

0xbfffdd83
0x726d6d68
0xbfffdd75
0x69276e00
0xbfffdd95

The next five lines are easiest to see pictorally. Since we are printing *b as a string, we have to treat *b as a pointer to the first character in the string, and print characters until we hit the NULL character:

The five strings are:

uukb'unrb;;
vlay
h
'unrb;;
acsy

The next set of lines sets p to equal a, and then backs it up 40 bytes. In other words, p equals 0xbfffdda4.

The output is:

0x6a0079
0x78617167
0x27007a79
0x2e636e79
0x2e0069

For the next set of lines, we start with pp equaling 0xbfffddf8. Each successive print statement treats the value of the last print statement as a pointer and prints what it points to. Annotated:

Output:

0xbfffddf8
0xbfffddfc
0xbfffddf4
0xbfffdd74
0x616c776b

And of the next word, we set c, d and q to 0xbfffdd84. The following table helps see what each of the eight values is. Hexadecimal makes doing the "mod 4" operation easy, as you just have to look at the last digit of q[i]:

i old d q[i] q[i]%4 new d c[i]
00xbfffdd840x27626b7510xbfffdd85'k'
10xbfffdd850x62726e7510xbfffdd86'b'
20xbfffdd860x3b3b30xbfffdd89'n'
30xbfffdd890x6x6a716110xbfffdd8a'r'
40xbfffdd8a0x6c00687110xbfffdd8b'b'
50xbfffdd8b0x786b000000xbfffdd8b'b'
60xbfffdd8b0x2700627a20xbfffdd8d';'
70xbfffdd8d0x7363616d10xbfffdd8e'\0'

Therefore, printing c as a string will get you: "kbnrbb;"

Finally, the c++ was a typo, because setting p to c means that p is not aligned. Therefore, if you told me "Bus Error", you were correct. Some machines (like my mac) don't worry about p being aligned. So, if it's not aligned, it will print the four bytes, starting with the 'b', as two-digit hex characters in reverse order: 0x62726e62.

Therefore, the answer is:

0xbfffdd83
0x726d6d68
0xbfffdd75
0x69276e00
0xbfffdd95

uukb'unrb;;
vlay
h
'unrb;;
acsy

0x6a0079
0x78617167
0x27007a79
0x2e636e79
0x2e0069

0xbfffddf8
0xbfffddfc
0xbfffddf4
0xbfffdd74
0x616c766b

kbnrbb;

0x62726e62  -- or Bus error


Grading

Each part was worth 5 points. Therefore, question 1 was worth 35, and question 2 was worth 30.