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
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] |
0 | 0x100168 | 0x100168 | 1852138855 |
1 | 0x10017c | 0x100180 | 1952514153 |
2 | 0x10014c | 0x100154 | 1677749871 |
3 | 0x100148 | 0x100154 | 1677749871 |
4 | 0x100144 | 0x100154 | 1677749871 |
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:
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 |
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] |
0 | 0xbfffdd84 | 0x27626b75 | 1 | 0xbfffdd85 | 'k' |
1 | 0xbfffdd85 | 0x62726e75 | 1 | 0xbfffdd86 | 'b' |
2 | 0xbfffdd86 | 0x3b3b | 3 | 0xbfffdd89 | 'n' |
3 | 0xbfffdd89 | 0x6x6a7161 | 1 | 0xbfffdd8a | 'r' |
4 | 0xbfffdd8a | 0x6c006871 | 1 | 0xbfffdd8b | 'b' |
5 | 0xbfffdd8b | 0x786b0000 | 0 | 0xbfffdd8b | 'b' |
6 | 0xbfffdd8b | 0x2700627a | 2 | 0xbfffdd8d | ';' |
7 | 0xbfffdd8d | 0x7363616d | 1 | 0xbfffdd8e | '\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 |