20

I'm relatively new to C++ and working on a fairly large C++ project at work. I notice handfuls of functions that take double pointers as parameters for objects that the function will instantiate on the heap. Example:

int someFunc(MyClass** retObj) {
    *retObj = new MyClass();

    return 0;
}

I'm just not sure why double pointers are always used, in this project, instead of just a single pointer? Is this mostly a semantic cue that it's an out/return parameter, or is there a more technical reason that I'm not seeing?

Bret Kuhns
  • 4,034
  • 5
  • 31
  • 43
  • 2
    because otherwise you would modify a local copy, not the variable that holds the pointer. And don't forget there are references, which is a cleaner way. – Gene Bushuyev Dec 13 '11 at 19:25
  • I forgot the actual value of the pointer is copied in. I was thinking it was by-reference implicitly, but that comes from my Java background. – Bret Kuhns Dec 13 '11 at 19:41

5 Answers5

31

The double pointer pattern is used so that the newly allocated MyClass can be passed to the caller. For example

MyClass* pValue;
someFunc(&pValue);
// pValue now contains the newly allocated MyClass

A single pointer is insufficient here because parameters are passed by value in C++. So the modification of the single pointer would only be visible from within someFunc.

Note: When using C++ you should consider using a reference in this scenario.

int someFunc(MyClass*& retObj) {
  retObj = new MyClass();
  return 0;
}

MyClass* pValue;
someFunc(pValue);

This allows you to pass the argument by reference instead of by value. Hence the results are visible to the caller.

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 1
    Thanks Jared, out of the stunningly quick 5 answers in 1 minute of my question, your's makes the most sense. My brain was implying reference-to-pointer, thus my confusion. Sometimes I get Java references mixed up with C++ pointers/references. Since the `new` allocation just returns a memory location, the local pointer by-value wouldn't be visible outside `someFunc`. Using a reference makes a whole lot more sense than double pointers. Seems some of the early developers of this project (early 90's) were mostly C guys forced to use C++. References appear almost nowhere in the code. – Bret Kuhns Dec 13 '11 at 19:39
  • 1
    @Rob: I humbly disagree. In a proper C++ way, a smart pointer would be used, so that there is no leak. – Matthieu M. Dec 13 '11 at 19:58
  • @MatthieuM. very true. Mainly wanted to get across the reason for a double pointer here and how to avoid that problem in C++ vs. perfect C++ idiom for the function. Would need to know more details about the function to give the "best" C++ answer – JaredPar Dec 13 '11 at 20:09
  • I've advocated for the use of the smart pointers available in MSVC10 wherever possible, but too often I end up having to cough up a raw pointer to some existing class. Then I have to track down to see if that class makes a mess of things by exposing the raw pointer elsewhere. So far, I haven't found a single place that I could reliably use a smart pointer without rewriting existing components :-( That said, I don't think @Rob is incorrect. Std lib aside, `*&` would be a C++ idiom, as apposed to the C-like double pointer. – Bret Kuhns Dec 13 '11 at 20:13
  • 1
    @bkuhns: I agree, this is more C++ like, I disagreed with the use of the expression "**the** C++ idiom" :) – Matthieu M. Dec 13 '11 at 20:44
8

The short answer is that parameters in C++ are passed by value, so your function receives a copy of that pointer. Once you overwrite it inside your function, the change is lost.

Your snippet however wants the change to be visible from the outside, so it needs a way to overwrite the actual pointer to the object, so it has to get a copy of a pointer to the pointer to the class, so it can overwrite the inner pointer and have it be visible from the outside.

Blindy
  • 65,249
  • 10
  • 91
  • 131
3

Using a single pointer just wouldn't work. Consider:

int someFunc(MyClass* retObj) {
    retObj = new MyClass();
    return 0;
}

MyClass* ptr = null;
someFunc(ptr);
// ptr is still null and we've got a memory leak

There are ways to make this work other than using a pointer to pointer, relative merits of which could be debated.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
3

Those two stars (double pointer) means a "pointer-to-a-pointer". This is a way of getting around the restriction where you can't return two things from a function in C++ (in your case, a return code indicating success or failure, and the newly allocated object).

Jack Edmonds
  • 31,931
  • 18
  • 65
  • 77
1

The canonical way to return an X is to pass a pointer to X. If X is a "pointer to MyClass", the canonical way to return it is to pass a "pointer to pointer to MyClass". You can't just pass a pointer to a MyClass to the function because the caller has no idea what the value of that pointer should be.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278