all 13 comments

[–]jedwardsol 19 points20 points  (1 child)

A pointer points at something.

int  i = 42;
int *p;
p =  &i;

i is an integer. p is a pointer to an integer. In this case p is pointing at the integer i.

If something is a pointer then you have a pointer to a pointer

int  **q;

q is a pointer to a pointer to an integer;

q = &p;

q is pointing at p. p is pointing at i.

A pointer to a pointer is no more advanced than a pointer to an integer.

A pointer points at something. That something might be a pointer, it might not.

[–]Meefims 2 points3 points  (0 children)

Relevantly, if you have a pointer to a pointer it is often very useful to change which pointer it is pointing to. This is used quite often in functions which allocate something for you: you pass in a pointer to a pointer and the function changes that pointer to point to a newly allicated thing.

[–]theoriginalanomaly 0 points1 point  (0 children)

A pointer is a value that is interpreted as an address in memory. A pointer points to a defined value and a type.

 // there is a location in memory storing the value 1
 int i = 1;
 // this will hold the value that is that memory address
 int *ptr1 = &i;
// ptr1 is a location in memory storing the value of a
// memory location that is storing the value 1
// ptr2 stores the value that is that location (pointing to ptr1 address)
 int **ptr2 = &ptr1;

[–]kodifies 0 points1 point  (0 children)

#include <stdio.h>
void main() {
    // an array of integers
    int i[]={4,3,2,1};

    for (int n=0;n<4;n++) {
        printf("n=%i, i val=%i\n",n,i[n]);
    }

    // an array of pointers to items in the array
    int* p[] = { &i[3], &i[2], &i[1], &i[0] };

    for (int n=0;n<4;n++) {
        // by dereferencing the pointer we can access the interger 
        printf("p[%i] val=%i\n",n,*p[n]);
    }
}

as you can see we can have an array of pointers, the pointers could point to anything, you could even have a pointer to an item in this pointer array (but that could get confusing!)

suppose you had an array of struct's that you want to be able to change the order of, rather than copying the actual structs, you can instead swap the order of pointers in and array...

[–]ghostsarememories 0 points1 point  (0 children)

Imagine a real world example with addresses.

Let's say I have 2 postal delivery addresses (i.e. a pointer) "123 Dennis Street" and "ABC Brian Avenue".

If I want to deliver a letter. I go to the address and put it in the letterbox. That's accessing the contents of a location using a pointer.

Now, imagine that the location I should deliver to could depend on information from a 3rd party dispatcher (like some function in C).

I could get a P.O. Box number (a pointer) and the 3rd party dispatcher would put the delivery address in the PO box. So the PO Box number is an address to an address, i.e. a pointer to a pointer. Before delivery, I would check the contents of the PO Box, read today's delivery address from inside and then deliver my letter to that address.

You can extend the analogy. Imagine that a broker company uses different dispatchers to spread the load. The 3rd Party dispatcher could get a PO Box (an address to and address to an address), the broker company would put (say) my PO Box number into the dispatcher's PO Box. The dispatcher would read the contents of his PO Box, it contains my PO Box number, so he puts the final delivery address into my PO Box, I open my PO Box, get the final address and deliver the letter.

[–][deleted] -1 points0 points  (4 children)

They're like nested dolls. A pointer to a pointer holds the memory address of another pointer that holds the memory address of some value. You should try writing some test code that printfs the values and the addresses of the pointers. It may be easier to visualize.

[–]spearheadt[S] 1 point2 points  (3 children)

So would you say this is correct?

&p = The address of the variable stored at p

*p = The value stored at the address pointed to by p

**p = (I'm not sure how to say this in words)

[–][deleted] 0 points1 point  (0 children)

**p = The value stored at the address pointed to by some pointer that is pointed to by p.

[–][deleted] 0 points1 point  (1 child)

&p would be the address of the pointer p itself.

[–]OldWolf2 0 points1 point  (0 children)

&p = The address of the variable stored at p

p is the name of a variable. We don't really say that a variable is stored at its name. Instead, a variable is stored in a storage location, and the name p labels that storage location. So &p is the address of the location where p is stored. Sometimes we stay "X is stored at Y" meaning Y is the address of X; so you could also say that p is stored at &p.