When should a double pointer be used in C? Can anyone explain with a example?
What I know is that a double pointer is a pointer to a pointer. Why would I need a pointer to a pointer?
When should a double pointer be used in C? Can anyone explain with a example?
What I know is that a double pointer is a pointer to a pointer. Why would I need a pointer to a pointer?
Strings are a great example of uses of double pointers. The string itself is a pointer, so any time you need to point to a string, you'll need a double pointer.
1. Basic Concept -
When you declare as follows : -
1. char *ch - (called character pointer)
- ch contains the address of a single character.
- (*ch) will dereference to the value of the character..
2. char **ch -
'ch' contains the address of an Array of character pointers. (as in 1)
'*ch' contains the address of a single character. (Note that it's different from 1, due to difference in declaration).
(**ch) will dereference to the exact value of the character..
Adding more pointers expand the dimension of a datatype, from character to string, to array of strings, and so on... You can relate it to a 1d, 2d, 3d matrix..
So, the usage of pointer depends upon how you declare it.
Here is a simple code..
2. Another Application of Double Pointers -
(this would also cover pass by reference)
Suppose you want to update a character from a function. If you try the following : -
The output will be AA. This doesn't work, as you have "Passed By Value" to the function.
The correct way to do that would be -
Now extend this requirement for updating a string instead of character.
For this, you need to receive the parameter in the function as a double pointer.
In this example, method expects a double pointer as a parameter to update the value of a string.
If you want to have a list of characters (a word), you can use
char *word
If you want a list of words (a sentence), you can use
char **sentence
If you want a list of sentences (a monologue), you can use
char ***monologue
If you want a list of monologues (a biography), you can use
char ****biography
If you want a list of biographies (a bio-library), you can use
char *****biolibrary
If you want a list of bio-libraries (a ??lol), you can use
char ******lol
... ...
yes, I know these might not be the best data structures
Usage example with a very very very boring lol
Output:
Here is a SIMPLE answer!!!!
BUT! if you want a function to do that for you, and you want the result to persist after the function is done, you need do some extra work, you need a new pointer3 just to point to pointer1, and pass pointer3 to the function.
here is a fun example (take a look at the output bellow first, to understand!):
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 stringa
.What happens at the line
Function_1(&a, b);
?The "value" of
&main::a
(an address) is copied into the parameterstd::string* Function_1::a
. ThereforeFunction_1::a
is a pointer to (i.e. the memory address of) the stringmain::a
.The "value" of
main::b
(an address in memory) is copied into the parameterstd::string* Function_1::b
. Therefore there are now 2 of these addresses in memory, both null pointers. At the lineb = a;
, the local variableFunction_1::b
is then changed to equalFunction_1::a
(=&main::a
), but the variablemain::b
is unchanged. After the call toFunction_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 stringmain::a
.But the variable
b
is now being passed as a pointer to a pointer. The "value" of&main::b
(the address of the pointermain::b
) is copied intostd::string** Function_2::b
. Therefore within Function_2, dereferencing this as*Function_2::b
will access and modifymain::b
. So the line*b = a;
is actually settingmain::b
(an address) equal toFunction_2::a
(= address ofmain::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 areconst
. Generally, if you callf(x)
, ifx
is an object you should be able to assume thatf
won't modifyx
. But ifx
is a pointer, then you should assume thatf
might modify the object pointed to byx
.)One thing I use them for constantly is when I have an array of objects and I need to perform lookups (binary search) on them by different fields.
I keep the original array...
Then make an array of sorted pointers to the objects.
You can make as many sorted pointer arrays as you need, then use a binary search on the sorted pointer array to access the object you need by the data you have. The original array of objects can stay unsorted, but each pointer array will be sorted by their specified field.