Pointers
Consider the following code. When you name your variables, whether they're pointers or integers or whatever, the name is a mnemonic, an alias, for a memory address. A convict and his number are irretrievably linked, but the number is not the convict, and is cheaper to feed. Suppose you write these statements:
int iValue = 25; int *pIntOne; int *pIntTwo = iNumber; pIntOne = &iValue; int iCopy;
The first statement will cause the compiler to set aside for you a memory location large enough to hold an integer value. It will also initialize the memory with the value, 25. Nice compiler. The memory set aside for you may live in one place or another, depending upon the context, but you know where it is in a useful way because you named it and the name is an alias for a numerical location in your memory area.
The second statement will cause the compiler to set aside enough memory to hold a pointer. It is not initialized; it contains nothing useful. There are many for whom this will be a surprise. When they declare a pointer, they expect it to automagically generate an object to point to (a mate, the other half of the pair mentioned in the beginning) as well as a value for itself that points there. These people have a predictable and recurring agenda: they write code, compile it, run it, then log on to a forum and post a question asking why they got a segmentation fault or core dump. Possibly there's a reboot before that final step. This code,
char *buffer;
scanf ("%s", buffer);
The third statement will cause a problem. iNumber has not been defined at this point. If one could actually get away with the declaration, it would constitute a likely path through a hatchet fight. Presumably your compiler will gripe and you won't actually have to walk through the fight. This statement looks okay on the surface. After all, It meets the requirements of having two things in a pointer-object relationship. The relationship is a lie. The second thing doesn't exist.
The next statement stores a value in pIntOne. The value is the address of the variable, iValue. It is not the value of iValue. It is merely a reference. The final statement sets aside additional memory for another value, but stores no meaningful value there. Assuming 32-bit integers, 32-bit pointers, and memory for our declarations beginning at hex address 0x1000, the memory will look like this:
0x1000: iValue contents: 25 0x1004: pIntOne contents: 0x1000 0x1008: pIntTwo contents: unknown, junk 0x100c: iCopy contents: unknown, junk
The value of pIntOne (yes it holds a value) is 0x1000. "pIntTwo = pIntOne" will assign the value, 0x1000, to pIntTwo, not the value 25. To use the 25 pointed to by pIntOne, one must 'dereference' it. One does this with the indirection operator, '*' (and sometimes the '->' operator, which is not discussed here). pIntOne has the value, 0x1000. *pIntOne has the value, 25 (the value in memory location 0x1000). "pIntTwo = pIntOne" (notice pIntOne isn't dereferenced here) assigns the value, 0x1000, found in pIntOne, to pIntTwo. "iCopy = *pIntTwo" (notice the dereference operator) assigns the value, 25, found at the location referred to by pIntTwo, not in pIntTwo, to iCopy.
Of course, we could have written directly into the variable, so what good is a pointer, you ask? On occassion, one may need to write to a variable whose location is not known until runtime. Perhaps it has been dynamically allocated in response to changing conditions, and the only reference we have to it is a pointer. Thanks to our pointer conduit, memory now looks like this:
0x1000: iValue contents: 25 0x1004: pIntOne contents: 0x1000 0x1008: pIntTwo contents: 0x1000 0x100c: iCopy contents: 25
What is a pointer?Confustoids