1. What is a pointer and how is it declared?
2. What is the Modula-2 symbol ^ called?
3. What is the difference between a reference to point and a reference to point^?
4. With what two types are all pointer variables assignment compatible?
5. How can pointers be used to make a program more efficient even without using dynamic memory?
6. What does it mean to say that some pointer expressions must be guarded? What is the error being guarded against?
7. What procedures can be employed to do pointer arithmetic?
8. What is a dangling pointer and how does it get that way?
9. Explain how pointers can be used to simulate the action of a variable parameter.
10. Explain the operation of the machine stack. What is a stack pointer?
11. What is an activation record?
12. Explain how the use of activation records on a stack allows recursion.
13. Why would one not call the use of activation records on a stack a true dynamic activity?
14. What is the heap?
15. What two pervasive (built-in) procedures does Modula-2 employ to manage the heap?
16. What two unusual (magical) properties do these two procedures have?
17. The ISO standard says that the two procedures mentioned in the last question are often translated into two library procedures. What two library procedures are these, and why does the standard say often?
18. What restriction on the use of function procedure identifiers was highlighted in this chapter?
19. A program needs a pointer to access every dynamic item, yet the goal in using dynamic memory is to be free of the limitations on static memory. How is this problem avoided?
20. What are two applications of dynamic memory?
21. What is a linked list?
22. Name and explain two extensions to the linked list ADT.
23. Write a definition module for a linked list ADT. You may employ any base data type you wish.
24. What is an opaque data type and what does the ISO standard require them to be re-declared as?
25. Why was this limitation on the nature of opaque data types made?
26. How does the handling of variant dynamic records differ from that of ordinary dynamic records?
27. Why is it that a dynamic variant record might occupy different amounts of memory depending on the value of its tag field(s)?
28. A static variant record has the same amount of memory regardless of the value of its tag fields. Explain why this is the case.
29. A record type with a variant is found as the type of a field in another record. Do the sub-record tags affect memory allocation for the entire record?
30. How would you refer to the integer item ultimately pointed to through the variable handle below?
TYPE HandleType = POINTER TO POINTER TO INTEGER; VAR handle : HandleType;
31. The use of SIZE (point^) could, in theory, cause a run-time error if the pointer had a value of NIL. In actual fact, this will never take place in the ISO version of Modula-2 because of the way in which SIZE is evaluated. Explain.
32. Write a small program to check on the way your implementation handles Storage.ALLOCATE and Storage.DEALLOCATE. Does a failure to allocate memory result in a NIL value being assigned to the pointer? Does DEALLOCATE assign NIL to the pointer? What does your system actually do when a reference to point^ is made while point has the value NIL?
33. Consider the following declarations. Devise a short test harness and determine the amount of memory allocated for the variants on your machine.
TYPE Date = RECORD day: [0 .. 31]; month: [0 .. 11]; year: CARDINAL; END; Index = CARDINAL; Frac = REAL; STRING = ARRAY [0 .. 80] OF CHAR; Person = RECORD name, birthPlace: STRING; birthDate: Date; CASE tag OF student: (* Nothing--null record *) |faculty: rank: STRING |staff: department, position: STRING END END;
34. Declare your own variant record type with one or more nested variants, check the validity of your declarations with the compiler you are using, and test the possible tag field values for the amount of memory allocation on your machine. While you are at it, investigate the use of the alternate version of NEW and of TSIZE for such purposes.
35. As in number 34, but this time declare your own variant record type with two or more non-nested variants and one or more nested variant and test the possible tag field values for the amount of memory allocation on your machine.
36. By finding and printing the address of value parameters and/or a local variable, verify that your system operates a stack for activation records in the manner described in this chapter. Are the first stack addresses greater or less than the addresses of main program memory variables? Does the stack grow up or down in memory (or neither?)
37. Declare variables of two different dynamic types of different sizes. Allocate memory to one, get and print (interesting task) the address, then deallocate the memory and reallocate it, first to the same pointer, then to one of the other type, printing out the addresses each time. What conclusion do you come to about the location of the heap on your machine relative to the main program variables and the stack? Does the memory given up on a deallocate get used when a new allocation is requested?
38. Declare and fill with values a dynamic array of reals (dimension chosen at run time) and then print the values out to verify you have done it correctly.
39. Implement and test for yourself the sorting of a collection of three records with auxiliary pointers as suggested in section 12.2.
40. Implement and test more complete and bullet-proof versions of the modules MakeRecords and GetPrintRecords in section 12.6. Your improvements should be substantial, not just cosmetic.
41. Test the module OpaquePoints in section 12.9 with an appropriate test harness.
42. Assemble the procedures of section 12.10 into a test harness, and add procedures to find and to delete a specific item.
43. Complete the module TwoWayList in section 12.11 by adding a procedure to delete a specific item by index number and another procedure to delete one by the data it contains.
44. Modify the module TwoWayList in section 12.11 to have another data field, say, a student number, and two more forward and backward pointers. New items should be added in such a way that they are in order by one set of pointers for the names (as shown in the example) and by the other set of pointers for the numbers. Deletion should be by name or number (student number, not index number.) The procedures to write the data need to be modified as well for testing purposes.
45. Implement and test the linked list ADT you defined in question 23 above.
46. Define, implement and test a dynamic string ADT.
47. Define, implement and test a dynamic array of reals ADT whose dimensions can be established at run time. Include and test in a client program the code to add and to multiply two of these.
48. Devise, implement, and test a means of storing and retrieving (in random access fashion) variant records of different lengths from a disk file.