Still don't understand pointers

I've been trying to understand pointers for the past week and a half or so. I still don't at all understand it. Any help would be greatly appreciated.
'&' is address in memory
*pi == i and pi == &i
pointer is indicated by '*'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;

int main ()
{
   int i =10;
   int ar[] = {1,2,3,4,5,6};
   
   int *pi = &i; // use '&' for single variable
   
   int *par = ar; // dont use '&' for array
   
   cout << "*pi= " << *pi <<  ",  pi= " << pi << ",  &i=" << &i << "\n\n";
   
   
   for( int i=0; i<6; i++)
   	cout << "ar[i]= " << ar[i] << ",  par[i]= " << par[i] << ",  *(par+i)= " << *(par+i) <<"\n";
 
   
return 0;
}


output:
*pi= 10,  pi= 0x7fffe80474,  &i=0x7fffe80474 

ar[i]= 1, par[i]= 1, *(par+i)= 1 
ar[i]= 2, par[i]= 2, *(par+i)= 2 
ar[i]= 3, par[i]= 3, *(par+i)= 3 
ar[i]= 4, par[i]= 4, *(par+i)= 4 
ar[i]= 5, par[i]= 5, *(par+i)= 5 
ar[i]= 6, par[i]= 6, *(par+i)= 6
Last edited on
Here's a visual which might help. Keep it open as you read my explanation:

http://imgur.com/3Rf50RG


Variables are essentially a "box" that contains information. You can think of memory as millions and millions of these boxes available to you.

Each box has an "address" that tells the computer where to find it in the sea of other boxes. So whenever you make a variable, that variable is assigned an address in memory:

1
2
int foo = 5;
int bar = 10;

For this example, let's say that the computer decides to place 'foo' at address '1002' and 'bar' is placed at address '1006'

The value of '5' is then placed inside the box at address 1002
and the value of '10' is placed inside the box at address 1006



Pointers are variables just like regular ints. Only instead of holding a number, they hold an address.
 
int* ptr = &foo;  // let's say 'ptr' is placed at address 1004 


Here, the & symbol is the address of operator. It gives us the address of foo... which, for our example, is 1002.

This means that the value of 1002 (address of foo) is placed in the box at address 1004 (address of ptr).

This is all represented in the above linked image.




So how when you work with normal variables, you can use the variable name to access the contents of that box:

1
2
3
4
cout << foo;  // <- this will print '5' because the contents of the 'foo' box contains 5
cout << ptr;  // <- this will print '1002' because the contents of the 'ptr' box contains 1002
   // (assuming that's the address of foo.  Note that the computer will likely put it at a
   //  different address so if you try this for real it will print something else) 



The difference with pointers is that you can use "indirection" with them. This allows you to "follow" their address:

 
cout << *ptr; // <- this will print '5'.  See below 

Here, the * symbol is the indirection operator. This means, instead of printing the contents of the ptr box... it will look in the pointer box, get that address, then look in whatever box that is at that address.

So *ptr will look in the ptr box, see that it contains 1002, then will go to address 1002, and print the contents of that box.

And since box 1002 contains '5', that's what it will print.


EDIT: bigtime ninja'd =P
Last edited on
https://www.youtube.com/watch?v=6pmWojisM_E

It is a silly video but it does cover the basics
Last edited on
@disch,
so, can I assign a constant value to a pointer, or do I have to do it via a variable? For example, would this be correct?
1
2
int *pi = 7;
cout<< *pi;
Pointers aren't different from any other type, I think once you understand this your life will get much easier.

When you declare a variable, say int, you are asking for enough space in memory to hold an int, and for the the value in that memory location to be interpreted as an integer.
1
2
3
4
5
int x = 1234;
/* Memory
location : value
0x00     : zero memory not used
0x10     : 1234 */


x is now associated with that memory address ( 0x10 ). So, when you do something like: std::cout << x; you are asking for the program to reach into memory location 0x10 and interpret the value there as an integer. Remember, everything in memory is just zero and ones, the type of variable defines how those zeros and ones are interpreted.

The value stored within an int is interpreted as an integer. Likewise, the value stored within a char is interpreted as a character.

The value stored within a pointer is interpreted as a memory location. However, it doesn't give us much use to just have a memory location*, so when we declare pointers, we also declare the type of data that they point to:
1
2
3
4
5
6
7
int x = 1234;
int *x_ptr = &x;
/* Memory
location : value
0x00     : zero memory not used
0x10     : 1234
0x20     : 0x10 */


Now that we have declared a pointer, there are various operators that we can use to help us understand what is going on. Namely, the dereferece operator ( * ) and the address-of operator ( & ):
1
2
3
4
5
std::cout <<      x; // prints 1234
std::cout <<     &x; // prints 0x10
std::cout <<  x_ptr; // prints 0x10
std::cout << &x_ptr; // prints 0x20
std::cout << *x_ptr; // prints 1234 


Pointers are often misunderstood. I think this has to do with the fact that the homework assigned to learn about pointers is more of a syntax puzzle than actually understanding them.

* I did put an asterisk as if I had something more to say, which is true. However, I think it would be better if you became unafraid of pointers before diving deeper into them. Let me know if you have any more questions.
so, can I assign a constant value to a pointer, or do I have to do it via a variable?


Well.... Yes you can do that, but you really shouldn't.

If you cast the constant value, then yes you can assign it:

 
int* p = (int*)7;


Although this will generally not be useful, as you have no way of knowing what the contents of address 7 is supposed to be.

Typically, referring to random places in memory is a very bad idea. You should stick to places where you know what the memory is. This is why you'll pretty much always use it with other variables.
There is one constant you can and will assign to a pointer: nullptr, or, before C++11, NULL. It denotes a null pointer, a pointer which does not points to the valid value.
Topic archived. No new replies allowed.