When should a double indirection be used in C? Can anyone explain with a example?
What I know is that a double indirection is a pointer to a pointer. Why would I ne
The following is a very simple C++ example that shows that if you want to use a function to set a pointer to point to an object, you need a pointer to a pointer. Otherwise, the pointer will keep reverting to null.
(A C++ answer, but I believe it's the same in C.)
(Also, for reference: Google("pass by value c++") = "By default, arguments in C++ are passed by value. When an argument is passed by value, the argument's value is copied into the function's parameter.")
So we want to set the pointer b
equal to the string a
.
#include
#include
void Function_1(std::string* a, std::string* b) {
b = a;
std::cout << (b == nullptr); // False
}
void Function_2(std::string* a, std::string** b) {
*b = a;
std::cout << (b == nullptr); // False
}
int main() {
std::string a("Hello!");
std::string* b(nullptr);
std::cout << (b == nullptr); // True
Function_1(&a, b);
std::cout << (b == nullptr); // True
Function_2(&a, &b);
std::cout << (b == nullptr); // False
}
// Output: 10100
What happens at the line Function_1(&a, b);
?
The "value" of &main::a
(an address) is copied into the parameter std::string* Function_1::a
. Therefore Function_1::a
is a pointer to (i.e. the memory address of) the string main::a
.
The "value" of main::b
(an address in memory) is copied into the parameter std::string* Function_1::b
. Therefore there are now 2 of these addresses in memory, both null pointers. At the line b = a;
, the local variable Function_1::b
is then changed to equal Function_1::a
(= &main::a
), but the variable main::b
is unchanged. After the call to Function_1
, main::b
is still a null pointer.
What happens at the line Function_2(&a, &b);
?
The treatment of the a
variable is the same: within the function, Function_2::a
is the address of the string main::a
.
But the variable b
is now being passed as a pointer to a pointer. The "value" of &main::b
(the address of the pointer main::b
) is copied into std::string** Function_2::b
. Therefore within Function_2, dereferencing this as *Function_2::b
will access and modify main::b
. So the line *b = a;
is actually setting main::b
(an address) equal to Function_2::a
(= address of main::a
) which is what we want.
If you want to use a function to modify a thing, be it an object or an address (pointer), you have to pass in a pointer to that thing. The thing that you actually pass in cannot be modified (in the calling scope) because a local copy is made.
(An exception is if the parameter is a reference, such as std::string& a
. But usually these are const
. Generally, if you call f(x)
, if x
is an object you should be able to assume that f
won't modify x
. But if x
is a pointer, then you should assume that f
might modify the object pointed to by x
.)