Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding C++ pointers (when they point to a pointer)

I think I understand references and pointers pretty well. Here is what I (think I) know:

int i = 5; //i is a primitive type, the value is 5, i do not know the address.
int *ptr;  //a pointer to an int. i have no way if knowing the value yet.
ptr = &i;  //now i have an address for the value of i (called ptr)
*ptr = 10; //Go to the value in ptr, use it to find a location and store 10 there

Please feel free to comment or correct these statements.

Now I'm trying to make the jump to arrays of pointers. Here is what I do not know:

char **char_ptrs = new char *[50];
Node **node_ptrs = new Node *[50];

My understanding is that I have 2 arrays of pointers, one set of pointers to chars and one to nodes. So if I wanted to set the values, I would do something like this:

char_ptrs[0] = new char[20];
node_ptrs[0] = new Node;

Now I have a pointer, in the 0 position of my array, in each respective array. Again, feel free to comment here if I'm confused.

So, what does the ** operator do? Likewise, what is putting a single * next to the instantiation doing (*[50])? (what is that called exactly, instantiation?)

like image 245
Stephano Avatar asked May 11 '10 21:05

Stephano


People also ask

What happens when a pointer points to a pointer?

Pointer assignment between two pointers makes them point to the same pointee. So the assignment y = x; makes y point to the same pointee as x . Pointer assignment does not touch the pointees. It just changes one pointer to have the same reference as another pointer.

Can a pointer point to a pointer in C?

The first pointer is used to store the address of the variable. And the second pointer is used to store the address of the first pointer. That is why they are also known as double-pointers. We can use a pointer to a pointer to change the values of normal pointers or create a variable-sized 2-D array.

How do you get the value that a pointer is pointing to?

To get the value pointed to by a pointer, you need to use the dereferencing operator * (e.g., if pNumber is a int pointer, *pNumber returns the value pointed to by pNumber . It is called dereferencing or indirection).

What is understanding pointers in C?

Well, a pointer holds a memory location or address of another variable in your code. Because a pointer itself is a variable, it can be modified, changing the address in some way. The pointer can also manipulate data stored at the address it references. Pointers are declared like any other variable.


2 Answers

A few comments:

*ptr = 10; // Doesn't need to "go get" the value. Just overwrites it.

Also:

char **char_ptrs = new char *[50];
Node **node_ptrs = new Node *[50];

It is easier to think that you have two arrays. However, technically (and as far as the compiler is concerned) what you have is two pointers. One is a pointer to a (pointer to a char) and the other is a pointer to a (pointer to a node).

This is easily seen by the declarations of your variables, which, by the way, can be most easily read right-to-left:

char **char_ptrs

Reading right to left: char_ptrs is a pointer to a pointer to char

Putting a * next to a pointer is properly called dereferencing that pointer. Since arrays do not technically exist, operator [] on arrays is also a dereferencing operation: arr[i] is another way of writing *(arr + i). To properly understand this, you need to be familiar with pointer arithmetic.

More than one consecutive *s: each one dereferences the result of the expression it operates on. So when writing:

char c = **char_ptrs;

what happens is:

char_ptrs is a pointer to a pointer to a char. Dereferencing it once (for the rightmost *) gets you its value, which is a pointer to a char. Dereferencing that value (for the leftmost *) gives you its own value in turn, which is a char. In the end, c contains the value of the char stored in memory at the place where the pointer pointed to by char_ptrs (in other words, the first pointer in your array) points.

Conversely, if you write **char_ptrs = 'a'; then you are changing the value in that memory location.

like image 170
Jon Avatar answered Sep 28 '22 06:09

Jon


** is just * twice, so a pointer to a pointer.

When put next to a type, * binds left, not right. Saying new char *[50] is actually new char* [50] and instantiates an array of 50 char*.

like image 25
Ignacio Vazquez-Abrams Avatar answered Sep 28 '22 06:09

Ignacio Vazquez-Abrams