6 +1 nake it this im suspicion. Pointers in dynamic languages such as Perl,LISP.and Java work a little differently.The run-time system sets each point tO NULL W en it is allocated e乙ASa locate and fix pointer bugs in dynamic lang ges.The run-time checks are also a reason such languages alwaysn at least aitte slower than a compiled language like C Two Levels One way to think about pointer code is that operates at two levels- pointer level and anc onne ust be a to the (1)the B 3 (3).and the whole thing vill blow u both levels -make a memory drawing during your design to make sure it's right. ve basic features of pintees.dereferencing and assigning are the only concepts you need to build pointer code.However.in order to talk about pinter code y Pointer Type Syntax A pointer type in C is just the pointee type followed by a asterisk().. int* type:pointer to int float* type:pointer to float struct fraction* type:pointer to struct fraction struct fraction** type:pointer to struct fraction* Pointer Varia ables rial and name of the new va t like any does not assign a pointee for the pointer- -the pointer starts out with a bad value. int*numptr: /Declare the int*(pointer to int)variable "numptr" pointer,but not the pointee inter
6 Quite the opposite — most languages make it easy to omit this important step. You just have to program carefully. If your code is crashing, a bad pointer should be your first suspicion. Pointers in dynamic languages such as Perl, LISP, and Java work a little differently. The run-time system sets each pointer to NULL when it is allocated and checks it each time it is dereferenced. So code can still exhibit pointer bugs, but they will halt politely on the offending line instead of crashing haphazardly like C. As a result, it is much easier to locate and fix pointer bugs in dynamic languages. The run-time checks are also a reason why such languages always run at least a little slower than a compiled language like C or C++. Two Levels One way to think about pointer code is that operates at two levels — pointer level and pointee level. The trick is that both levels need to be initialized and connected for things to work. (1) the pointer must be allocated, (1) the pointee must be allocated, and (3) the pointer must be assigned to point to the pointee. It's rare to forget step (1). But forget (2) or (3), and the whole thing will blow up at the first dereference. Remember to account for both levels — make a memory drawing during your design to make sure it's right. Syntax The above basic features of pointers, pointees, dereferencing, and assigning are the only concepts you need to build pointer code. However, in order to talk about pointer code, we need to use a known syntax which is about as interesting as....a syntax. We will use the C language syntax which has the advantage that it has influenced the syntaxes of several languages. Pointer Type Syntax A pointer type in C is just the pointee type followed by a asterisk (*)... int* type: pointer to int float* type: pointer to float struct fraction* type: pointer to struct fraction struct fraction** type: pointer to struct fraction* Pointer Variables Pointer variables are declared just like any other variable. The declaration gives the type and name of the new variable and reserves memory to hold its value. The declaration does not assign a pointee for the pointer — the pointer starts out with a bad value. int* numPtr; // Declare the int* (pointer to int) variable "numPtr". // This allocates space for the pointer, but not the pointee. // The pointer starts out "bad
-Reference To fe ntee suitable for rator can go to the left of any variable,and it computes a reference to that variable.The code below uses a pointer and an to produce the earlier num/numPtr example. num42☐4 numPtr void NumPtrExample0【 int num; int*numPtr; num =42; %trhgmeinceyeao8fac8i0agmcandstoe北naumPtr It is possible to use in a way which compiles fine but which creates problems at rur the full discussion of how to correctly use&is in Section 2.For now we will just The*Operator-Dereference The star operator(*)dereferences a pointer.The is a unary operator which goes to the left of the pointer it dereferences.The pointer must have a pointee,or it's a runtime error Example Pointer Code With the syntax defined,we can now write some pointer code that demonstrates all the pointer rules... void pointerTest() ate three integers and two pointers int*p: int*qi XXX D b 2 XX XG p=&a; /set p to refer to a
7 The & Operator — Reference To There are several ways to compute a reference to a pointee suitable for storing in a pointer. The simplest way is the & operator. The & operator can go to the left of any variable, and it computes a reference to that variable. The code below uses a pointer and an & to produce the earlier num/numPtr example. num 42 numPtr void NumPtrExample() { int num; int* numPtr; num = 42; numPtr = # // Compute a reference to "num", and store it in numPtr // At this point, memory looks like drawing above } It is possible to use & in a way which compiles fine but which creates problems at run time — the full discussion of how to correctly use & is in Section 2. For now we will just use & in a simple way. The * Operator — Dereference The star operator (*) dereferences a pointer. The * is a unary operator which goes to the left of the pointer it dereferences. The pointer must have a pointee, or it's a runtime error. Example Pointer Code With the syntax defined, we can now write some pointer code that demonstrates all the pointer rules... void PointerTest() { // allocate three integers and two pointers int a = 1; int b = 2; int c = 3; int* p; int* q; // Here is the state of memory at this point. // T1 -- Notice that the pointers start out bad... a 1 b 2 c 3 p q p = &a; // set p to refer to a
Theo o mave pontee a1☐ p b2 ”兰5 Dereferences and assigmmentsi things up a1☐4X□ b13☐ g Bad Pointer Example ine.but at un-tim nointer will corupt memory in some way.The program will crash sooner or later.It is up to the programmer to ensure that each pointer i assigned a pointee before it is used.The follow ng example shows a simple example of the bad code and a drawing of how memory is likely to react.. the pointer,but not the pointee *p=42 /this dereference is a serious runtime error /What happens at runtime when the bad pointer is dereferenced... pX××
8 q = &b; // set q to refer to b // T2 -- The pointers now have pointees a 1 b 2 c 3 p q // Now we mix things up a bit... c = *p; // retrieve p's pointee value (1) and put it in c p = q; // change p to share with q (p's pointee is now b) *p = 13; // dereference p to set its pointee (b) to 13 (*q is now 13) // T3 -- Dereferences and assignments mix things up a 1 b 13 c 1 p q } Bad Pointer Example Code with the most common sort of pointer bug will look like the above correct code, but without the middle step where the pointers are assigned pointees. The bad code will compile fine, but at run-time, each dereference with a bad pointer will corrupt memory in some way. The program will crash sooner or later. It is up to the programmer to ensure that each pointer is assigned a pointee before it is used. The following example shows a simple example of the bad code and a drawing of how memory is likely to react... void BadPointer() { int* p; // allocate the pointer, but not the pointee *p = 42; // this dereference is a serious runtime error } // What happens at runtime when the bad pointer is dereferenced... p Pow!
.A noi The dereference .Allocating a pointer does not automatically assign it to refer to a pointee nter to refer to a specific pointee is a separate operation Assignment between two pointers makes them refer to the same pointee which introduces sharing. Section 1-Extra Optional Material Extra:How Do Pointers Work In Java lava has pointe rs.but they are not manipulated with explicit oper Java.simple data typessuch siand haperate ust or su d Th ds t types.and no automatically be implemented with ponterfand bare arrays or objects.Or ers s are intrins share e the D the s.Thava ob ct re in ically the garbage collector(Section 4),takes care of the deallocation automatically at the end of the function. public void Javashallow()( 88=w888 create in the declaration) baha8aoeageaaoo8e9nmeat 11 a.Bar();/This could just as well be written b.Bar(); The Java approach has two main features... Fewer bugs.Because the every time it is used,so NULL pointer dereferences are caught here they cr hs can make ao
9 Pointer Rules Summary No matter how complex a pointer structure gets, the list of rules remains short. • A pointer stores a reference to its pointee. The pointee, in turn, stores something useful. • The dereference operation on a pointer accesses its pointee. A pointer may only be dereferenced after it has been assigned to refer to a pointee. Most pointer bugs involve violating this one rule. • Allocating a pointer does not automatically assign it to refer to a pointee. Assigning the pointer to refer to a specific pointee is a separate operation which is easy to forget. • Assignment between two pointers makes them refer to the same pointee which introduces sharing. Section 1 — Extra Optional Material Extra: How Do Pointers Work In Java Java has pointers, but they are not manipulated with explicit operators such as * and &. In Java, simple data types such as int and char operate just as in C. More complex types such as arrays and objects are automatically implemented using pointers. The language automatically uses pointers behind the scenes for such complex types, and no pointer specific syntax is required. The programmer just needs to realize that operations like a=b; will automatically be implemented with pointers if a and b are arrays or objects. Or put another way, the programmer needs to remember that assignments and parameters with arrays and objects are intrinsically shallow or shared— see the Deep vs. Shallow material above. The following code shows some Java object references. Notice that there are no *'s or &'s in the code to create pointers. The code intrinsically uses pointers. Also, the garbage collector (Section 4), takes care of the deallocation automatically at the end of the function. public void JavaShallow() { Foo a = new Foo(); // Create a Foo object (no * in the declaration) Foo b = new Foo(); // Create another Foo object b=a; // This is automatically a shallow assignment -- // a and b now refer to the same object. a.Bar(); // This could just as well be written b.Bar(); // There is no memory leak here -- the garbage collector // will automatically recycle the memory for the two objects. } The Java approach has two main features... • Fewer bugs. Because the language implements the pointer manipulation accurately and automatically, the most common pointer bug are no longer possible, Yay! Also, the Java runtime system checks each pointer value every time it is used, so NULL pointer dereferences are caught immediately on the line where they occur. This can make a programmer much more productive
10 ways the ammer applications Extra:How Are Pointers Implemented In The Machine? How are pointers implemented?The short explanation is that every area of memory in the chine has a numeric idress like 1000 r20452 rea of mcmory is the a rea of memory d to that e the stored there.Pointer assignment just copies the numeric address from one pointer to another.The NULL value is generally just the numeric address 0- cor put never allocates address can be used represent NULL starts out ith a random value.The inter has not vet heen assi igned the specific address of a valid pointee.This is why dereference 8 mh6品PeTh时pohm Extra:The Term "Reference" The word "reference"means almost the same thing as the word "pointer".The difference is that "referenc tends to be used in a discussion of pointer issues which is not specific Cany particular】 nguage or 0n. ddr ed in the hrase"reference parameter"which is a technique which uses pointer parameters for two- way communication between functions-this technique is the subject of Section 3. e Bad Pointer Bugs So C e tha nter but forget to set it to refer ponte?meru for poter onsm that cmtveprogrammer makes this error repeatedly.Why?The problem is that we are trained by the tools we use Simple variables don' th xtra setup.You can allocate a simple variable,such as written has trained nably that a variable may he used once it is de clared uire the extra ini ialization before use.It's unfortunate,in a way,that pointers happen look like oth ables,since t ma mbent easy to f orget that the rules for wh ell.Try forget
10 • Slower. Because the language takes responsibility for implementing so much pointer machinery at runtime, Java code runs slower than the equivalent C code. (There are other reasons for Java to run slowly as well. There is active research in making Java faser in interesting ways — the Sun "Hot Spot" project.) In any case, the appeal of increased programmer efficiency and fewer bugs makes the slowness worthwhile for some applications. Extra: How Are Pointers Implemented In The Machine? How are pointers implemented? The short explanation is that every area of memory in the machine has a numeric address like 1000 or 20452. A pointer to an area of memory is really just an integer which is storing the address of that area of memory. The dereference operation looks at the address, and goes to that area of memory to retrieve the pointee stored there. Pointer assignment just copies the numeric address from one pointer to another. The NULL value is generally just the numeric address 0 — the computer just never allocates a pointee at 0 so that address can be used to represent NULL. A bad pointer is really just a pointer which contains a random address — just like an uninitialized int variable which starts out with a random int value. The pointer has not yet been assigned the specific address of a valid pointee. This is why dereference operations with bad pointers are so unpredictable. They operate on whatever random area of memory they happen to have the address of. Extra: The Term "Reference" The word "reference" means almost the same thing as the word "pointer". The difference is that "reference" tends to be used in a discussion of pointer issues which is not specific to any particular language or implementation. The word "pointer" connotes the common C/C++ implementation of pointers as addresses. The word "reference" is also used in the phrase "reference parameter" which is a technique which uses pointer parameters for twoway communication between functions — this technique is the subject of Section 3. Extra: Why Are Bad Pointer Bugs So Common? Why is it so often the case that programmers will allocate a pointer, but forget to set it to refer to a pointee? The rules for pointers don't seem that complex, yet every programmer makes this error repeatedly. Why? The problem is that we are trained by the tools we use. Simple variables don't require any extra setup. You can allocate a simple variable, such as int, and use it immediately. All that int, char, struct fraction code you have written has trained you, quite reasonably, that a variable may be used once it is declared. Unfortunately, pointers look like simple variables but they require the extra initialization before use. It's unfortunate, in a way, that pointers happen look like other variables, since it makes it easy to forget that the rules for their use are very different. Oh well. Try to remember to assign your pointers to refer to pointees. Don't be surprised when you forget