751
z Invalid pointers. A programmer is free to store any address in a pointer,
including a totally invalid address. A common problem is dereferencing
a null pointer. These problems can be guarded against by using asser-
tion macros to check that pointers are never null prior to dereferencing
them. Even worse, if a piece of data is misinterpreted as a pointer, deref-
erencing it can cause the program to read or write an essentially random
memory address. This usually results in a crash or other major problem
that can be very tough to debug.
Many game engines make heavy use of pointers, because they are by far
the fastest, most effi cient, and easiest-to-work-with way to implement object
references. However, experienced programmers are always wary of pointers,
and some game teams turn to more sophisticated kinds of object references,
either out of a desire to use safer programming practices or out of necessity.
For example, if a game engine relocates allocated data blocks at runtime to
eliminate memory fragmentation (see Section 5.2.2.2), simple pointers cannot
be used. We either need to use a type of object reference that is robust to mem-
ory relocation, or we need to manually fi x up any pointers into every relocated
memory block at the time it is moved.
14.5.2. Smart Pointers
A smart pointer is a small object that acts like a pointer for most intents and pur-
poses but avoids most of the problems inherent with native C/C++ pointers. At
its simplest, a smart pointer contains a native pointer as a data member and
provides a set of overloaded operators that make it act like a pointer in most
ways. Pointers can be dereferenced, so the * and -> operators are overloaded
to return the address as expected. Pointers can undergo arithmetic operations,
so the +, -, ++, and -- operators are also overloaded appropriately.
Because a smart pointer is an object, it can contain additional meta-data
and/or take additional steps not possible with a regular pointer. For example, a
smart pointer might contain information that allows it to recognize when the ob-
ject to which it points has been deleted and start returning a NULL address if so.
Smart pointers can also help with object lifetime management by cooper-
ating with one another to determine the number of references to a particular
object. This is called reference counting. When the number of smart pointers
that reference a particular object drops to zero, we know that the object is no
longer needed, so it can be automatically deleted. This can free the program-
mer from having to worry about object ownership and orphaned objects.
Smart pointers have their share of problems. For one thing, they are rela-
tively easy to implement, but they are extremely tough to get right. There are
a great many cases to handle, and the std::auto_ptr class provided by the
14.5. Object References and World Queries