When to pass a pointer to pointer as argument to functions in C++?

23,251

Solution 1

C++

In C++, you can pass by reference, and you do that when you want modifications of the parameter to affect the argument which the caller passed in. That is, passing by reference represents an out or in/out parameter.

You pass a pointer if the function wants a pointer (obviously), or if you want to signify an optional output parameter - since a reference always has to bind to something, but a pointer can be null.

By the same logic, pass a pointer to pointer if the function actually needs double pointers (very rare in C++) or if you want to signify an optional [in-]out parameter of pointer type (also quite rare).

Here are some examples (contrived, but should demonstrate the thing):

int square(int x)  //pass int by value
{ return x * x; }

void squareRoots(double in, double &plus, double &minus)  //pass double by reference
{
  plus = sqrt(in);
  minus = -plus;
}

int toNumber(String s, bool *ok = nullptr)  //optional out parameter
{
  try {
    int val = s.toNumber();
    if (ok)
      *ok = true;
    return val;
  } catch (NotANumber &) {
    if (ok)
      *ok = false;
    return 0;
  }
}

int computeAge(Person *person)  //pass pointer by value
{
  if (!person)
    return -1;
  else
    return now() - person->dateOfBirth();
}

bool createPerson(Person * &person)  //pass pointer by reference
{
  if (tooManyPeople())
    return false;
  person = new Person();
  return true;
}

int sum(int **values)  //pass double pointer by value
{
  if (!values)
    return 0;
  int res = 0;
  while (*values) {
    res += **values;
    ++values;
  }
  return res;
}

bool allocate(int ** &arr)  //pass double pointer by reference
{
  if (!enoughMemory())
    return false;
  arr = new int*[1024];  // array of 1024 pointers to int
  return true;
}

bool newNode(Node **node = nullptr)  //optional out parameter
{
  Node *added = dataStructure.createNode();
  if (node)
    *node = added;
  return added;
}

(Note 1: I am only talking about non-const references here, since that's relevant to the pass by pointer vs. pass by reference. Passing by const-reference usually means "the object is too big to copy needlessly," and does not apply really when pointers to pointers could be involved).

(Note 2: The above examples are horrible in that they use owning raw pointers, dynamic array allocation etc. In actual C++, you would use smart pointers, std::vector etc. instead. That's why pointers to pointer are rare in C++).


C

In C, double pointers are more common, since C does not have a reference type. Therefore, you also use a pointer to "pass by reference." Where & is used in a parameter type in the C++ examples above, * would be used in C (and dereferenced when manipulating the parameter). One example:

void squareRoots(double in, double *plus, double *minus)  //pass double "by reference"
{
  *plus = sqrt(in);
  *minus = -*plus;
}

Solution 2

void SomeFun1(int *);
void SomeFun2(int **);
int i;
int *ptr = &i;

//when you want value of ptr should remain unchanged, but you want to change only value of i, use,
SomeFun1(int *)

//when you want value of ptr should change. i.e, it should point to some other memory other than i, use,
SomeFun2(int **);

Solution 3

You pass a pointer to pointer as argument when you want the function to set the value of the pointer.

You typically do this when the function wants to allocate memory (via malloc or new) and set that value in the argument--then it will be the responsibility of the caller to free it. It is better than returning it as a function return value, because there is no possibility of the caller ignoring the return value by mistake and causing a leak by not freeing it.

You might also want to use this if you are returning multiple values.

Another reason to do this is when you want to make want to return the value optionally (ie the pointer to pointer can be NULL). For example, look at strtol() it has an optional endptr.

Note: you should never set this pointer to a stack variable.

Solution 4

  • You would use <type>** when you want to pass an array of pointers.

Example:

int main(int argc, char **argv) {   // argv is an array of char*
  • You would also use it if you want to be able to change the pointer address (in C++ you could pass a pointer reference instead in this case).

Solution 5

What hasn't been mentioned is dynamically allocating 2D array - essentially, you would have an array of pointers pointing to other pointers.

Share:
23,251
Nejat
Author by

Nejat

A fan of Qt/C++/QML.

Updated on March 13, 2020

Comments

  • Nejat
    Nejat about 4 years

    Here i read an article about when to pass pointers as argument of functions. But i want to know about some situations in which you should pass a pointer to pointer as argument of a function. To be more clear i want to know when one should use something like:

    func(int **x);
    
  • EmiliOrtega
    EmiliOrtega over 3 years
    and how would I call each function in each case ? somefun1(ptr) and somefun2(&ptr) respectively ?