Passing references to pointers in C++

C++PointersReference

C++ Problem Overview


As far as I can tell, there's no reason I shouldn't be allowed to pass a reference to a pointer in C++. However, my attempts to do so are failing, and I have no idea why.

This is what I'm doing:

void myfunc(string*& val)
{
    // Do stuff to the string pointer
}

// sometime later 
{
    // ...
    string s;
    myfunc(&s);
    // ...
}

And I'm getting this error:

>cannot convert parameter 1 from 'std::string *' to 'std::string *&'

C++ Solutions


Solution 1 - C++

Your function expects a reference to an actual string pointer in the calling scope, not an anonymous string pointer. Thus:

string s;
string* _s = &s;
myfunc(_s);

should compile just fine.

However, this is only useful if you intend to modify the pointer you pass to the function. If you intend to modify the string itself you should use a reference to the string as Sake suggested. With that in mind it should be more obvious why the compiler complains about you original code. In your code the pointer is created 'on the fly', modifying that pointer would have no consequence and that is not what is intended. The idea of a reference (vs. a pointer) is that a reference always points to an actual object.

Solution 2 - C++

The problem is that you're trying to bind a temporary to the reference, which C++ doesn't allow unless the reference is const.

So you can do one of either the following:

void myfunc(string*& val)
{
    // Do stuff to the string pointer
}


void myfunc2(string* const& val)
{
    // Do stuff to the string pointer
}

int main()
// sometime later 
{
    // ...
    string s;
    string* ps = &s;
    
    myfunc( ps);   // OK because ps is not a temporary
    myfunc2( &s);  // OK because the parameter is a const&
    // ...
    
    return 0;
}

Solution 3 - C++

Change it to:

  std::string s;
  std::string* pS = &s;
  myfunc(pS);

EDIT:

This is called ref-to-pointer and you cannot pass temporary address as a reference to function. ( unless it is const reference).

Though, I have shown std::string* pS = &s; (pointer to a local variable), its typical usage would be : when you want the callee to change the pointer itself, not the object to which it points. For example, a function that allocates memory and assigns the address of the memory block it allocated to its argument must take a reference to a pointer, or a pointer to pointer:

void myfunc(string*& val)
{
//val is valid even after function call
   val = new std::string("Test");

}

Solution 4 - C++

&s produces temporary pointer to string and you can't make reference to temporary object.

Solution 5 - C++

Try:

void myfunc(string& val)
{
    // Do stuff to the string pointer
}

// sometime later 
{
    // ...
    string s;
    myfunc(s);
    // ...
}

or

void myfunc(string* val)
{
    // Do stuff to the string pointer
}

// sometime later 
{
    // ...
    string s;
    myfunc(&s);
    // ...
}

Solution 6 - C++

EDIT: I experimented some, and discovered thing are a bit subtler than I thought. Here's what I now think is an accurate answer.

&s is not an lvalue so you cannot create a reference to it unless the type of the reference is reference to const. So for example, you cannot do

string * &r = &s;

but you can do

string * const &r = &s;

If you put a similar declaration in the function header, it will work.

void myfunc(string * const &a) { ... }

There is another issue, namely, temporaries. The rule is that you can get a reference to a temporary only if it is const. So in this case one might argue that &s is a temporary, and so must be declared const in the function prototype. From a practical point of view it makes no difference in this case. (It's either an rvalue or a temporary. Either way, the same rule applies.) However, strictly speaking, I think it is not a temporary but an rvalue. I wonder if there is a way to distinguish between the two. (Perhaps it is simply defined that all temporaries are rvalues, and all non-lvalues are temporaries. I'm not an expert on the standard.)

That being said, your problem is probably at a higher level. Why do you want a reference to the address of s? If you want a reference to a pointer to s, you need to define a pointer as in

string *p = &s;
myfunc(p);

If you want a reference to s or a pointer to s, do the straightforward thing.

Solution 7 - C++

Welcome to C++11 and rvalue references:

#include <cassert>
#include <string>

using std::string;

void myfunc(string*&& val)
{
	assert(&val);
	assert(val);
	assert(val->c_str());
    // Do stuff to the string pointer
}

// sometime later 
int main () {
    // ...
    string s;
    myfunc(&s);
    // ...
}

Now you have access to the value of the pointer (referred to by val), which is the address of the string.

You can modify the pointer, and no one will care. That is one aspect of what an rvalue is in the first place.

Be careful: The value of the pointer is only valid until myfunc() returns. At last, its a temporary.

Solution 8 - C++

I have just made use of a reference to a pointer to make all the pointers in a deleted binary tree except the root safe. To make the pointer safe we just have to set it to 0. I could not make the function that deletes the tree (keeping only the root) to accept a ref to a pointer since I am using the root (this pointer) as the first input to traverse left and right.

void BinTree::safe_tree(BinTree * &vertex ) {
    if ( vertex!=0 ) {  // base case
    	safe_tree(vertex->left);    // left subtree.
            safe_tree(vertex->right);   //  right subtree.
          // delete vertex;  // using this delete causes an error, since they were deleted on the fly using inorder_LVR. If inorder_LVR does not perform delete to the nodes, then, use delete vertex;
        vertex=0;  // making a safe pointer
    }
} // end in

Bottom line, a reference to a pointer is invalid when the formal parameter is the (this) pointer.

Solution 9 - C++

I know that it's posible to pass references of pointers, I did it last week, but I can't remember what the syntax was, as your code looks correct to my brain right now. However another option is to use pointers of pointers:

Myfunc(String** s)

Solution 10 - C++

myfunc("string*& val") this itself doesn't make any sense. "string*& val" implies "string val",* and & cancels each other. Finally one can not pas string variable to a function("string val"). Only basic data types can be passed to a function, for other data types need to pass as pointer or reference. You can have either string& val or string* val to a function.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlexView Question on Stackoverflow
Solution 1 - C++ChrisView Answer on Stackoverflow
Solution 2 - C++Michael BurrView Answer on Stackoverflow
Solution 3 - C++aJ.View Answer on Stackoverflow
Solution 4 - C++n0rdView Answer on Stackoverflow
Solution 5 - C++SakeView Answer on Stackoverflow
Solution 6 - C++AriView Answer on Stackoverflow
Solution 7 - C++not-a-userView Answer on Stackoverflow
Solution 8 - C++MohdView Answer on Stackoverflow
Solution 9 - C++Robert GouldView Answer on Stackoverflow
Solution 10 - C++ShashikiranView Answer on Stackoverflow