Why and when is worth using pointer to pointer? [duplicate]
Possible Duplicate:
How do pointer to pointers work in C?
Hello,
Altough I think I passed the newbie phase in programming I still have some questions that somehow I can't find them explained. Yes, there are plenty of "how to"s overthere but almost always nobody 开发者_如何学运维explains why and/or when one technique is useful.
In my case I have discovered that in some cases a pointer to a pointer is used in C++. Is not a pointer to an object enough? Which are the benefits? Where or when should be used a pointer to a pointer? I feel little bit desorientated in this matter.
I hope time experienced expert could respond to this concerns that hopefully is shared by other no so experienced programers. ;-)
Thank you everyone.
Julen.
Well, it is somehow hard to answer to such a general question.
First answer of a C++ programmer will certainly be : Do not use pointers in C++ ! As you have a lot of safer ways to handle problems than pointers, one of your goal will be to avoid them in the first place :)
So pointers to pointers are seldom used in C++. They are mainly used in C. First, because in C, strings are "char*" so when you need a "pointer to a C string" you end with a "char**". Second, as you do not have references in C, when you need to have a function that modify a pointer or that give a pointer as an output value, you need to give a pointer to a pointer parameter. You typically find that in functions that allocate memory, as they give you a pointer to the allocated memory.
If you go the C++ way, try to avoid pointers, you usually have better ways.
my2c
In C, an argument is passed to a function that changes it, through a pointer. You will see the same with C++ for old or legacy code (int main(int argc, char** argv)
) , for code that will be accessed from C (COM / XPCOM) or with code that was written by someone used to C (or the C style).
From a "purely C++" standpoint, using pointer to pointer is in most situations a sign of poor coding style, as most situations that require a **
construct can (and should) be refactored to use safer alternatives (like std::
containers, or *&
parameters).
I can think of two use cases.
One is arrays as inherited from C. Arrays automatically decay to pointers to their first elements in many cases. If you happen to have an array of pointers, you get a pointer to a pointer for that.
(Something similar can happen when you have a std::vector
of pointers, BTW: A pointer is a perfect random access iterator and I have indeed seen std lib implementations using pointers for std::vector<>::iterator
. For a std::vector
of pointers, v.begin()
would return a pointer to a pointer.)
The other is for function arguments. For function arguments, taking something per pointer indicates that callers might call the function even if they don't have an object to pass in; they can pass in NULL
then. (Otherwise why take a pointer instead of a reference? See here for more details on this).
Taking a non-const
reference to a pointer would indicate that the called function might assign a new address to that pointer.
So taking a pointer to a pointer would indicate that the function might assign a new address to a pointer, if the caller passes in a pointer to it, but is callable with NULL
as well.
For example:
void f(int** ppi);
void g(int i);
void h()
{
f(NULL); // call `f()` only for its side-effects
int* pi = NULL;
f(&pi); // call `f()` and get some object in *pi
if(pi)
g(*pi); // use result
}
Where or when should be used a pointer to a pointer?
In a function that optionally may return pointer to caller, if the caller requests that. Frequently used by system APIs, some COM objects, etc.
int f(void** p = 0){
//.......
}
If caller provides p, then function passes pointer through p. If caller doesn't provide p, then no pointer is returned. May be useful for debugging purposes in certain situations.
Which are the benefits?
The question is too broad. Look, it is a VERY simple technique without some kind of mysterious benefits. You use it when you have to. That's all. There is no hidden meaning and no secret advantages of this concept - it is equivalent to asking "what are benefits of using letter \"e\" in english language".
Pointers to pointers have most relevance in C. Seldomly, you need them in C++. There you can work with containers from the std lib or with references.
There are two popular use cases in C though:
An array of pointers, most prominently used as argv to main(): the pointer gives the address to the array of argument strings (type char*). In C, the [] operators work on pointers to anything as pointers to anything are seen as an equivalent to arrays.
A function argument denoting a place where to store the address of something. Use case: In C, the return value is often used for error handling or state information. Arguments are used for carrying the payload. One example: A function "returns" an address to newly allocated memory, but using an argument. You give the function a pointer to the pointer that should afterwards point to the data. The function overwrites that space and for that, it needs a pointer to a pointer.
You only use them when employing manual memory management, something that's rare as hell in C++, therefore they're pretty useless. Even regular pointers are of questionable value in the majority of scenarios.
There're actually two use cases.
First, is when you call a function that has to return more than one value, some of which, are pointers. Then, you would provide her with an address of a pointer, so it could fill in the pointed pointer:
int *p1 = 0, *p2 = 0, *p3 = 0;
multi_malloc(&p1, &p2, &p3); // Allocates three pointers
Second is when you want to do sparse 2d arrays:
int main(int argc, char **argv)
This is a pointer to pointer. argv[i] is a pointer to char. This way, argv[i][j] is a char j in row i.
You will be happy to hear that there're nearly zero uses for pointer to pointer to pointer. int ***p;
is almost never useful.
精彩评论