Pointers to pointers are very commonly used as parameters that allocate & return a buffer, such as a string:
void SetValue(char** buf)
{
string s = "Hello, Ptr Ref";
*buf = new char[s.length()+1];
copy(s.begin(), s.end(), *buf);
(*buf)[s.length()] = 0;
}
int main()
{
char* buf = 0;
SetValue(&buf);
cout << buf;
delete [] buf;
return 0;
}
Similarly, instead of passing in a pointer to a pointer to the buffer you want to allocate & modify, you can pass in a reference to that buffer. This can help to clarify the semantics of your function to the caller, so that they don't do something like call SetValue(0);
void SetValue(char*& buf)
{
string s = "Hello, Ptr Ref";
buf = new char[s.length()+1];
copy(s.begin(), s.end(), buf);
buf[s.length()] = 0;
}
int main()
{
char* buf = 0;
SetValue(buf);
cout << buf;
delete [] buf;
return 0;
}
But even while the semantics of SetValue(char*&)
might be a bit clearer than the SetValue(char**)
version, there is still room for improvement. The question of who owns the resulting pointer comes to mind.
Keep in mind that while these examples are simplistic and contrived, implementations like this abound. In many of those cases where this is being done you have no choice -- for example, when calling WINAPI functions like FormatMessage() and asking it to allocate the buffer. But in many other cases where you write the function, there will be other ways to skin the cat. Arguably, better ways. Such as:
string GimmeValue()
{
return "Hello, String";
}
This might be better for a variety of reasons. It is (potentially) semantically more clear to return a value by value than to use outvals like pointers-to-pointer because the question of ownership is easily resolved. It is often better to avoid using operator new in places when a stack-allocated variable will do just fine, because you avoid potential memory leaks or defects due to delete
ing the buffer more than once.