A very general question: I was wondering why we use pointer to pointer? A pointer to pointer will hold the address of a pointer which in turn will point to another pointer. But, this could be achieved even by using a single pointer.
Consider the following example:
{
int number = 10;
int *a = NULL;
a = &number;
int *b = a;
int *pointer1 = NULL;
pointer1 = b; //pointer1 points to the address of number which has value 10
int **pointer2 = NULL;
pointer2 = &b; //pointer2 points to the address of b which in turn points to the address of number which has value 10. Why **pointer2??
return 0;
}
I think you answered your own question, the code is correct, what you commented isn't.
int number = 10;
is the value
int *pointer1 = b;
points to the address where int number is kept
int **pointer2 = &b;
points to the address where address of int number is kept
Do you see the pattern here??
address = * (single indirection)
address of address = ** (double indirection)
First of all, a pointer doesn't point to a value. It point to a memory location (that is it contains a memory address) which in turn contains a value. So when you write
pointer1 = b;
pointer1
points to the same memory location as b which is the variable number
. Now after that is you execute
pointer2 = &b;
Then pointer2
point to the memory location of b
which doesn't contains 10
but the address of the variable number
The following expressions are true:
*pointer2 == b
**pointer2 == 10
The following is not!
*pointer2 == 10
Pointer to pointer can be useful when you want to change to what a pointer points to outside of a function. For example
void func(int** ptr)
{
*ptr = new int;
**ptr = 1337;
}
int main()
{
int* p = NULL;
func(&p);
std::cout << *p << std::endl; // writes 1337 to console
delete p;
}
A stupid example to show what can be achieved :) With just a pointer this can not be done.
Your assumption is incorrect. pointer2
does not point to the value 10, but to the (address of the) pointer b
. Dereferencing pointer2
with the *
operator produces an int *
, not an int
.
You need pointers to pointers for the same reasons you need pointers in the first place: to implement pass-by-reference parameters in function calls, to effect sharing of data between data structures, and so on.
A simple example is an implementation of a matrix (it's an example, it's not the best way to implement matrices in C++).
int nrows = 10;
int ncols = 15;
double** M = new double*[nrows];
for(unsigned long int i = 0; i < nrows; ++i)
M[i] = new double[ncols];
M[3][7] = 3.1416;
You'll rarely see this construct in normal C++ code, since C++ has references. It's useful in C for "passing by reference:"
int allocate_something(void **p)
{
*p = malloc(whatever);
if (*p)
return 1;
else
return 0;
}
The equivalent C++ code would use void *&p
for the parameter.
Still, you could imagine eg a resource monitor like this:
struct Resource;
struct Holder
{
Resource *res;
};
struct Monitor
{
Resource **res;
void monitor(const Holder &h) { res = &h.res; }
Resource& getResource() const { return **res; }
}
Yes, it's contrived, but the idea's there - it will keep a pointer to the pointer stored in a holder, and correctly return that resource even when the holder's res
pointer changes.
Of course, it's a dangling dereference waiting to happen - normally, you'd avoid code like this.
In c such construction made sense, with bigger data structures. The OOP in C, because of lack of possibility to implement methods withing structures, the methods had c++ this
parameter passed explicitly. Also some structures were defined by a pointer to one specially selected element, which was held in the scope global to the methods.
So when you wanted to pass whole stucture, Eg a tree, and needed to change the root, or 1st element of a list, you passes a pointer-to-a-pointer to this special root
/ head
element, so you could change it.
Note: This is c-style implementation using c++ syntax for convienience.
void add_element_to_list(List** list, Data element){
Data new_el = new Data(element); // this would be malloc and struct copy
*list = new_el; //move the address of list, so it begins at new element
}
In c++ there is reference mechanismm and you generally you can implement nearly anything with it. It basically makes usage of pointers at all obsolete it c++, at least in many, many cases. You also design objects and work on them, and everything is hidden under the hood those two.
There was also a nice question lately "Why do we use pointers in c++?" or something like that.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.