Q: One of the difficulties with pointers is that often when we misuse them, our errors are not caught by the compiler at compile time; they occur at runtime. Which of the following result in compile-time errors? Which of the following result in runtime errors? Why?
A: a) A compile-time error occurs because when we
dereference tptr
, we get a character,
whereas sptr
is a pointer to a character.
Thus, the code is trying to assign a character pointer to a character,
which is a type conflict. b) No error occurs because both
tptr
and sptr
are character pointers. c) A runtime error is likely to occur because
no storage has been allocated for tptr
.
When we dereference tptr
, we cannot be sure
where it points. d) A runtime error is likely to occur because
assigning an integer pointer a fixed address is dangerous. When
dereferencing iptr
, we try to write 11 at
address 10, which is probably invalid. e) A compile-time error or
warning occurs because the code is trying to initialize an integer
pointer to an integer, which is a type conflict. f ) No error occurs
because although the code first performs the dangerous step of
initializing iptr
to a fixed address, it is
then immediately reset to NULL, which is valid.
Q: Recall that calculations
with pointers are performed using pointer arithmetic. If p
contains the address
0x10000000, what address does the following expression access? How
many bytes are accessed at this address?
*(p + 5)
A: The answer to this question
depends on the type of p
. Recall that when
we add an integer i to a pointer
p
, the result is not the address stored in
p
plus i bytes, but
the address in p
, plus
i times the number of bytes in the datatype
p
references. Since the question does not
state p
’s type, it is not possible to
determine the address accessed as a result of the expression. The type
of p
is also required to determine how many
bytes p
accesses. Therefore, it is also
impossible to determine the number of bytes accessed.
Q: The operation
list_rem_next removes an element from a linked
list (see Chapter 5).
If iptr
is an integer pointer we would like
set to an integer removed from a list, how might we call
list_rem_next as an alternative to the approach
presented in the chapter? A prototype for the function is shown here,
where list
is the list,
element
references the element preceding
the one to remove, and upon return, data
references the data removed.
int list_rem_next(List *list, ListElmt *element, void **data);
A: An alternative way
to call list_rem_next is shown here. In this
approach, iptr
is cast to a void pointer
instead of a pointer to a void pointer. This method is acceptable
because void pointers are compatible with all others. However, our
original approach is clearer because it is consistent with the
prototype of list_rem_next.
retval = list_rem_next(&list, element, (void *)&iptr);
3.16.48.181