tags:

views:

266

answers:

7

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.

+1  A: 

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.

Pavel Radzivilovsky
This is very C. In C++ you have references to pointers and you can do all this with them in a simpler (and, thus, less error prone) way.
Daniel Daranas
Hehe. `int ***p` looks like you censored something.
detly
IIRC, according to C++ standard, you can have up to 8 levels of de-referencing. Like int ********p
Aamir
@Aamir: I'm pretty sure there's no such restriction. Do you have a reference for it?
Mike Seymour
+3  A: 

Pointers to pointers have most relevance in C. In C++ you sheldomly need them. There you can work with containers from the std lib or with references.

There are two popular use cases in C though:

  1. 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.

  2. 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.

ypnos
+5  A: 

Hi,

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).

utnapistim
+6  A: 

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

neuro
-1 "Do not use pointers in C++". Seriously? So, I'm supposed to forget about DirectX programming, OpenGL, com objects, direct API calls? What's the point of programming without pointers? This sounds like useless syntaxic sugar to me.
SigTerm
sbi
@SigTerm: First thank you for explaining your downvote. Second I'm no expert in the API you speak about, but I think they are C APIs, no ? Of course one usecase of using pointers in C++ is using C APIs :) I perhaps should have said "Try to do not use pointers when designing things with C++". When you use APIs you have no choice. Moreover, as the OP question was about pointers to pointers, it seems to me that was not a desirable way of designing C++ code to use pointers to pointers. In fact when I write pointers I suppose I think raw pointers, as I use quite extensively smart pointers ;)
neuro
@sbi: Using pointers does is not equal to using new/delete. Pointers have a lot of use outside of dynamic memory allocation routines.
SigTerm
@neuro: Your first problem is that you do not explain WHY you think pointers are bad, and claim that "C++ programmer should not use pointers" without citing anyone or giving reasonable explanation. This already deserves a downvote. You did not mention any pointer problem either. Any advice given without a reasonable explanation most likely should be disregarded. Beliefs like this one make you write extra code (so it will look nice) without actually writing anything useful. Wrappers and smart pointers are not good in situations when you need good performance - because they add overhead.
SigTerm
@neuro: 2nd problem - dynamic memory allocation is not the only use for pointers. In many situations, processing raw memory block will result in faster and shorter code, than writing multiple class wrappers and allocating extra memory simply to avoid using pointers (so it will all "look nice"). Pointers and raw memory access is a must have feature for compiled language. If language feature exists, not using it reduces number of things you can do. IMO goal of programmer is to write short, maintainable code very quickly. Avoiding a feature has little to do with that.
SigTerm
@SigTerm: What other uses are there? For dealing with raw memory, I'd use `std::vector` and wouldn't care whether the underlying iterator type is a naked pointer or if that's wrapped by a thin compile-time layer.
sbi
Oh, and BTW: You're "writing multiple class wrappers and allocating extra memory simply to avoid using pointers" is blatant FUDing, and IMO worse than what you accuse neuro for.
sbi
+3  A: 

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
}
sbi
+3  A: 

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".

SigTerm
+1 this is so mainstream, yet so many other answers are saying 'you shouldn't do it!'
Will
+2  A: 

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.

DeadMG