|
|||||||||||||||||||||
|
|||||||||||||||||||||
|
Announcements
Services
Chapters
Feature Zones
|
What Are Pointers?Pointers are basically the same as any other variable. However, what is different about them is that instead of containing actual data, they contain a pointer to the memory location where information can be found. This is a very important concept. Many programs and ideas rely on pointers as the basis of their design, linked lists for example. Getting StartedHow do I define a pointer? Well, the same as any other variable, except you add an asterisk before its name. So, for example, the following code creates two pointers, both of which point to an integer: int* pNumberOne;
int* pNumberTwo;
Notice the "p" prefix in front of the two variable names? This is a convention used to indicate that the variable is a pointer. Now, let's make these pointers actually point to something: pNumberOne = &some_number;
pNumberTwo = &some_other_number;
The & (ampersand) sign should be read as "the address of" and causes the address in memory of a variable to be returned, instead of the variable itself. So, in this example, Now if we want to refer to the address of What We've Learned So Far: An ExamplePhew! That's a lot to take in. I'd recommend that if you don't understand any of those concepts, to give it another read through. Pointers are a complex subject and it can take a while to master them. Here is an example that demonstrates the ideas discussed above. It is written in C, without the C++ extensions. #include <stdio.h>
void main()
{
// declare the variables:
int nNumber;
int *pPointer;
// now, give a value to them:
nNumber = 15;
pPointer = &nNumber;
// print out the value of nNumber:
printf("nNumber is equal to : %d\n", nNumber);
// now, alter nNumber through pPointer:
*pPointer = 25;
// prove that nNumber has changed as a result of the above by
// printing its value again:
printf("nNumber is equal to : %d\n", nNumber);
}
Read through and compile the above code sample. Make sure you understand why it works. Then, when you are ready, read on! A Trap!See if you can spot the fault in the program below: #include <stdio.h>
int *pPointer;
void SomeFunction();
{
int nNumber;
nNumber = 25;
// make pPointer point to nNumber:
pPointer = &nNumber;
}
void main()
{
SomeFunction(); // make pPointer point to something
// why does this fail?
printf("Value of *pPointer: %d\n", *pPointer);
}
This program firstly calls the So, how can the problem be solved? The answer is by using a technique known as dynamic allocation. Please be aware that this is different between C and C++. Since most developers are now using C++, this is the dialect that the code below is using. Dynamic AllocationDynamic allocation is perhaps the key to pointers. It is used to allocate memory without having to define variables and then make pointers point to them. Although the concept may appear confusing, it is really simple. The following code demonstrates how to allocate memory for an integer: int *pNumber;
pNumber = new int;
The first line declares the pointer, double *pDouble;
pDouble = new double;
The formula is the same every time, so you can't really fail with this bit. What is different about dynamic allocation, however, is that the memory you allocate is not deleted when the function returns, or when execution leaves the current block. So, if we rewrite the above example using dynamic allocation, we can see that it works fine now: #include <stdio.h>
int *pPointer;
void SomeFunction()
{
// make pPointer point to a new integer
pPointer = new int;
*pPointer = 25;
}
void main()
{
SomeFunction(); // make pPointer point to something
printf("Value of *pPointer: %d\n", *pPointer);
}
Read through and compile the above code sample. Make sure you understand why it works. When Memory Comes, Memory GoesThere's always a complication and this one could become quite serious, although it's very easy to remedy. The problem is that although the memory that you allocate using dynamic allocation is conveniently left intact, it actually never gets deleted automatically. That is, the memory will stay allocated until you tell the computer that you've finished with it. The upshot of this is that if you don't tell the computer that you've finished with the memory, it will be wasting space that other applications or other parts of your application could be using. This eventually will lead to a system crash through all the memory being used up, so it's pretty important. Freeing the memory when you've finished with it is very simple: delete pPointer;
That's all there is to it. You have to be careful, however, that you pass a valid pointer, i.e. that is a pointer that actually points to some memory you've allocated and not just any old rubbish. Trying to #include <stdio.h>
int *pPointer;
void SomeFunction()
{
// make pPointer point to a new integer
pPointer = new int;
*pPointer = 25;
}
void main()
{
SomeFunction(); // make pPointer point to something
printf("Value of *pPointer: %d\n", *pPointer);
delete pPointer;
}
One line difference is all it took, but this line is essential. If you don't delete the memory, you get what is known as a "memory leak," where memory is gradually leaking away and can't be reused unless the application is closed. Passing Pointers to FunctionsThe ability to pass pointers to functions is very useful, but very easy to master. If we were to make a program that takes a number and adds five to it, we might write something like the following: #include <stdio.h>
void AddFive(int Number)
{
Number = Number + 5;
}
void main()
{
int nMyNumber = 18;
printf("My original number is %d\n", nMyNumber);
AddFive(nMyNumber);
printf("My new number is %d\n", nMyNumber);
}
However, the problem with this is that the To get around this problem, we can pass a pointer to where the number is kept in memory to the function, but we'll have to alter the function so that it expects a pointer to a number, not a number. To do this, we change #include <stdio.h>
void AddFive(int* Number)
{
*Number = *Number + 5;
}
void main()
{
int nMyNumber = 18;
printf("My original number is %d\n", nMyNumber);
AddFive(&nMyNumber);
printf("My new number is %d\n", nMyNumber);
}
Try coming up with an example of your own to demonstrate this. Notice the importance of the int * MyFunction();
In this example, Pointers to ClassesThere are a couple of other caveats with pointers, one of which is structures or classes. You can define a class as follows: class MyClass
{
public:
int m_Number;
char m_Character;
};
Then you can define a variable of type MyClass thing;
You should already know this. If not, try reading up on this area. To define a pointer to MyClass *thing;
...as you would expect. Then you would allocate some memory and make this pointer point to the memory: thing = new MyClass;
This is where the problem comes in: how then would you use this pointer? Well, normally you would write' class MyClass
{
public:
int m_Number;
char m_Character;
};
void main()
{
MyClass *pPointer;
pPointer = new MyClass;
pPointer->m_Number = 10;
pPointer->m_Character = 's';
delete pPointer;
}
Pointers to ArraysYou can also make pointers that point to arrays. This is done as follows: int *pArray;
pArray = new int[6];
This will create a pointer, int *pArray;
int MyArray[6];
pArray = &MyArray[0];
Note that, instead of writing Using Pointers to ArraysOnce you have a pointer to an array, how do you use it? Well, let's say you have a pointer to an array of #include <stdio.h>
void main()
{
int Array[3];
Array[0] = 10;
Array[1] = 20;
Array[2] = 30;
int *pArray;
pArray = &Array[0];
printf("pArray points to the value %d\n", *pArray);
}
To make the pointer move to the next value in the array, we can say #include <stdio.h>
void main()
{
int Array[3];
Array[0] = 10;
Array[1] = 20;
Array[2] = 30;
int *pArray;
pArray = &Array[0];
printf("pArray points to the value %d\n", *pArray);
pArray++;
printf("pArray points to the value %d\n", *pArray);
pArray++;
printf("pArray points to the value %d\n", *pArray);
}
You can also subtract values, so Note also that if you have a pointer to a value, e.g. One final word of warning for arrays is that if you allocate memory for an array using int *pArray;
pArray = new int[6];
...it must be deleted using the following: delete[] pArray;
Notice the Last WordsOne final note: you must not delete memory that you did not allocate using new, as in the following example: void main()
{
int number;
int *pNumber = number;
delete pNumber; // wrong - *pNumber wasn't allocated using new.
}
Common Questions and FAQQ: Why do I get "symbol undefined" errors on A: This is most likely caused by your source file being interpreted by the compiler as being a plain C file. The Q: What's the difference between A: Q: Can I use A: You should free memory with the equivalent routine to that used to allocated it. For instance, use ReferencesReferences are, to a certain degree, out of the scope of this article. However, since I've been asked many times by people reading this about them, I will discuss them briefly. They are very much related to pointers in that, in many cases, they can be used as a simpler alternative. If you recall from above, I mentioned that the ampersand (&) is read as "the address of" unless in a declaration. In the case of its presence in a declaration such as that shown below, it should be read as "a reference to." int& Number = myOtherNumber;
Number = 25;
The reference is like a pointer to int* pNumber = &myOtherNumber;
*pNumber = 25;
The other difference between pointers and references is that you cannot "reseat" a reference. That is to say that you cannot change what it is pointing to after its declaration. For instance, the following code would output "20." int myFirstNumber = 25;
int mySecondNumber = 20;
int &myReference = myFirstNumber;
myReference = mySecondNumber;
printf("%d", myFristNumber);
When in a class, the value of the reference must be set by the constructor in the following way: CMyClass::CMyClass(int &variable) : m_MyReferenceInCMyClass(variable)
{
// constructor code here
}
SummaryThis topic is very hard to master initially, so it is worth looking over at least twice: most people do not understand it immediately. Here are the main points again:
This is not an absolutely complete guide to pointers. There are a few other things that I could have covered in more detail, such as pointers to pointers, and also things that I chose not to cover at all, such as function pointers, which I believe are too complex for a beginner's article. There are also things which are used rarely enough that a beginner would be better off not being flummoxed by these unwieldy details. That's it! Try running some of the programs presented here and come up with some examples of your own. Updates
| ||||||||||||||||||||