Pointers are one of the most powerful and confusing aspects of the C language. A pointer is a variable that holds the address of another variable. To declare a pointer, we use an asterisk between the data type and the variable name:
int *pnPtr; // a pointer to an integer value double *pdPtr; // a pointer to a double value int* pnPtr2; // also valid syntax int * pnPtr3; // also valid syntax
Note that an asterisk placed between the data type and the variable name means the variable is being declared as a pointer. In this context, the asterisk is not a multiplication. It does not matter if the asterisk is placed next to the data type, the variable name, or in the middle — different programmers prefer different styles, and one is not inherently better than the other.
Since pointers only hold addresses, when we assign a value to a pointer, the value has to be an address. To get the address of a variable, we can use the address-of operator (&):
int nValue = 5; int *pnPtr = &nValue; // assign address of nValue to pnPtr
Conceptually, you can think of the above snippet like this:

It is also easy to see using code:
int nValue = 5; int *pnPtr = &nValue; // assign address of nValue to pnPtr cout << &nValue << endl; // print the address of variable nValue cout << pnPtr << endl; // print the address that pnPtr is holding
On the author’s machine, this printed:
0012FF7C 0012FF7C
The type of the pointer has to match the type of the variable being pointed to:
int nValue = 5; double dValue = 7.0; int *pnPtr = &nValue; // ok double *pdPtr = &dValue; // ok pnPtr = &dValue; // wrong -- int pointer can not point to double value pdPtr = &nValue; // wrong -- double pointer can not point to int value
Dereferencing pointers
The other operator that is commonly used with pointers is the dereference operator (*). A dereferenced pointer evaluates to the contents of the address it is pointing to.
int nValue = 5; cout << &nValue; // prints address of nValue cout << nValue; // prints contents of nValue int *pnPtr = &nValue; // pnPtr points to nValue cout << pnPtr; // prints address held in pnPtr, which is &nValue cout << *pnPtr; // prints contents pointed to by pnPtr, which is contents of nValue
The above program prints:
0012FF7C 5 0012FF7C 5
In other words, when pnPtr is assigned to &nValue:
pnPtr is the same as &nValue
*pnPtr is the same as nValue
Because *pnPtr is the same as nValue, you can assign values to it just as if it were nValue! The following program prints 7:
int nValue = 5; int *pnPtr = &nValue; // pnPtr points to nValue *pnPtr = 7; // *pnPtr is the same as nValue, which is assigned 7 cout << nValue; // prints 7
Pointers can also be assigned and reassigned:
int nValue1 = 5; int nValue2 = 7; int *pnPtr; pnPtr = &nValue1; // pnPtr points to nValue1 cout << *pnPtr; // prints 5 pnPtr = &nValue2; // pnPtr now points to nValue2 cout << *pnPtr; // prints 7
The null pointer
Sometimes it is useful to make our pointers point to nothing. This is called a null pointer. We assign a pointer a null value by setting it to address 0:
int *pnPtr; pnPtr = 0; // assign address 0 to pnPtr
or shorthand:
int *pnPtr = 0; // assign address 0 to pnPtr
Note that in the last example, the * is not a dereference operator. It is a pointer declaration. Thus we are assigning address 0 to pnPtr, not the value 0 to the variable that pnPtr points to.
C (but not C++) also defines a special preprocessor define called NULL that evaluates to 0. Even though this is not technically part of C++, it’s usage is common enough that it will work in every C++ compiler:
int *pnPtr = NULL; // assign address 0 to pnPtr
Because null pointers point to 0, they can be used inside conditionals:
if (pnPtr)
cout << "pnPtr is pointing to an integer.";
else
cout << "pnPtr is a null pointer.";
Null pointers are mostly used with dynamic memory allocation, which we will talk about in a few lessons.
The size of pointers
The size of a pointer is dependent upon the architecture of the computer — a 32-bit computer uses 32-bit memory addresses — consequently, a pointer on a 32-bit machine is 32 bits (4 bytes). On a 64-bit machine, a pointer would be 64 bits (8 bytes). Note that this is true regardless of what is being pointed to:
char *pchValue; // chars are 1 byte
int *pnValue; // ints are usually 4 bytes
struct Something
{
int nX, nY, nZ;
};
Something *psValue; // Something is probably 12 bytes
cout << sizeof(pchValue) << endl; // prints 4
cout << sizeof(pnValue) << endl; // prints 4
cout << sizeof(psValue) << endl; // prints 4
As you can see, the size of the pointer is always the same. This is because a pointer is just a memory address, and the number of bits needed to access a memory address on a given machine is always constant.
Quiz
1) What values does this program print? Assume a short is 2 bytes, and a 32-bit machine
short nValue = 7; // &nValue = 0012FF60 short nOtherValue = 3; // &nOtherValue = 0012FF54 short *pnPtr = &nValue; cout << &nValue << endl; cout << nValue << endl; cout << pnPtr << endl; cout << *pnPtr << endl; cout << endl; *pnPtr = 9; cout << &nValue << endl; cout << nValue << endl; cout << pnPtr << endl; cout << *pnPtr << endl; cout << endl; pnPtr = &nOtherValue; cout << &nOtherValue << endl; cout << nOtherValue << endl; cout << pnPtr << endl; cout << *pnPtr << endl; cout << endl; cout << sizeof(pnPtr) << endl; cout << sizeof(*pnPtr) << endl;
Quiz solutions
6.8 — Pointers, arrays, and pointer arithmetic
|
Index
|
6.6 — C-style strings
|
6.8 — Pointers, arrays, and pointer arithmetic
Index
6.6 — C-style strings
[...] the lesson on pointers, you learned that a pointer is a variable that holds the address of another variable. Function [...]
In the code
if (pnPtr) cout < < "pnPtr is pointing to an integer."; else cout << "pnPtr is a null pointer.you forgot the second double quotation mark and a semicolon.
*gets headache*
Well, that was almost fun to read!
What exactly is the POINT of a pointer? So far I’m just thinking of pointers as duplicates of other variables with similar functionality.
You can determine the address of a value a pointer is ‘pointing’ to, but can’t you just use the ‘&’ operator to do that anyway?
I don’t understand whyyyy! T^T
Setting a pointer to point at local non-array variable is an easy way to introduce pointers, but it’s not done all that often in practice.
Pointers are used for a lot of things:
1) They are the only way you can dynamically allocate memory in C++. This is by far their most common use. This topic is covered in lesson 6.9.
2) You can use them to step through the values in an array (as an alternative to array indices).
3) You can use them to pass a large struct/class to a function in a way that doesn’t involve copying the entire struct/class, which is inefficient (covered in lesson 7.4)
4) You can use them to pass a function as a parameter to another function (covered in lesson 7.8).
5) You can use them to achieve polymorphism when dealing with inheritance (covered in lesson 12.1).
All of these things are covered in future lessons, but you’ve got to start somewhere. And this is where. :)
Example is wrong. Look at cody’s comment above.
[ How did I miss that? Wow. Thanks, it's fixed. -Alex ]
[...] 6.7 — Introduction to pointers [...]
Very good tutorial. At last I could understand Pointers. :-)
Thank you, for the first time I’ve read something about pointers and it all makes sense and surprisingly easy going compared to other texts I’ve read.
[...] 2007 Prev/Next Posts « 6.7 — Introduction to pointers | Home | 6.9 — Dynamic memory allocation with new and delete » Wednesday, July [...]
if pointer holds the address of a variable, what if i want to know the pointer’s address it self how can i do that?
You can use the & operator to get the address of any variable (even a pointer).
eg.
int nX = 3; // nX has address 0x0012ff60. nX has value 3.
int *pnX = &nX; // pnX has address 0012ff54. pnX has value 0x0012ff60
cout << pnX; // prints value of pnX, which is 0x0012ff60
cout << &pnX; // prints address of pnX which is 0x0012ff54
I believe there is an error in the last example in the section “the null pointer” here: did you not mean to dereference the pointer inside the if-condition, in order to check wether or not it points to anything? Right now it is written without a dereference operator.
Keep coding. Use it for good :)
The if (pnPtr) test to see if the pointer is null. If it is a null pointer then the address it is pointing is 0 (false). If the pointer is allocated (not null) then pnPtr points to a address != 0 (which means true).
I don’t understand this statement, shouldn’t it be the other way around?:
“Note that in the last example, the * is not a dereference operator. It is a pointer declaration. Thus we are assigning address 0 to pnPtr, not the value 0 to the variable that pnPtr points to.”
When I use the following code:
I get the output
0013FF60
00000000
surely the address is 0013FF… and the value is 000?
Many thanks for the tutorials though, they’re amazing, you’re a saint!
The statement is okey. Assigning an address to a pointer means that u tell the pointer: “Point to this address”. This is done with the “&”.
U can change the value of the pointed object with “*”.
The pointer itself is a variable that has an address. It is impossible to have a variable at 0000 0000.
00000000 is not the value. See this:
Because the pointer is null, it is pointing to address 00000000. The address of the pointer is 0013FF60.
This is a wonderful tutorial – the examples here clearly step through all possible pointer/pointed-to configurations. Thanks so much!
Simple well explained tutorial.
Thanks a lot.
[...] So within our ParticleEmitter declaration we’ve declared that we’re going to have an x and y value to position our emitter on the screen and a rotation value to rotate the emitter over time. We also declare three methods, setup, update, and draw that will define what our emitter will do every time the application cycles through a frame. Lastly we declare an Array called “p” that will store all of the Particles that are currently on the screen. The pointer syntax(*) that declares the “p” array is out of the scope of this article, however you can learn about pointers and how they work in C++ via this excellent tutorial here. [...]
I have a question …i cannot understand something.
I have this simple code :
int *pValue;
*pValue = 4;
cout<<*pValue;
It's all ok..it prints 4;
I i declare another one my program crushes and i cannot understand why since is the same thing.
int *pValue, *nValue;
*pValue = 4;
*nValue = 5;
cout<<*pValue<<*nValue;
Something must be wrong, because the first code in which you declare only one pointer crashes too.
No memory allocated. That is why it crashes.
[...] KNOWLEDGE FOR THIS PROGRAM Integer Arrays Character Arrays BubbleSort Pointers Function Pointers – What Are They? Memcpy Sizeof [...]
on my computer (windows 7 64-bit) sizeof(pntr) returns 4 when I was expecting it to return 8 based on this tutorial. Does anyone know why this is?
Also my computer has 8gb of ram so if pointers are only 32-bit for some reason then surely only half the computers memory could be used? I don’t get it.
[...] [...]
I am working on MS visual Studio 2010. OS is win7. What I know is win7 is 64 bit OS. yet I get pointer size as 4. Why it is not 8?
int* A;
cout<<"\nSize of memory address is"<<sizeof(A);
Output is:
Size of memory address is4
Thanks for answer.