Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I return a const ref a to local variable in C++?

Tags:

c++

boost

I have a function for which I cannot change the function parameters. I need to return a const reference to a std::string created in this function. I tried to use boost shared_ptr, but this doesn't work. Why? How do I make this work?

const std::string& getVal(const std::string &key) {
  boost::shared_ptr<std::string> retVal(new std::string());
  ... //build retVal string with += operator based on key
  return *retVal;
}
like image 997
bob Avatar asked Mar 01 '23 22:03

bob


2 Answers

You can't return a reference to a local variable from a function with c++. Although in c++0x this is possible.

Allocate the string on the heap and manually cleanup later:

If you cannot change the function's interface, then you will need to create it on the heap and then manually delete it after.

//Remember to free the address that getVal returns
const std::string& getVal(const std::string &key) {
  std::string *retVal = new std::string();
  ... //build retVal string with += operator based on key
  return *retVal;
}

Same solution but not manually:

Since the above will eventually lead to a memory leak if you forget to free it manually. I would recommend to wrap this call into a class and use RAII. I.e. in the constructor, call getVal and set a member of this class to point to it. In the destructor of your class you would delete it.

Why the code you gave with shared_ptr does not work:

shared_ptr works via reference counting. Since you are destroying the only shared_ptr object (by scope), there are no references left and the memory will be freed. To get this to work you'd have to return a shared_ptr, but you said you cannot do this.

like image 73
Brian R. Bondy Avatar answered Mar 12 '23 00:03

Brian R. Bondy


You would need to return a boost shared_ptr, not a std::string. As soon as the function exits that shared_ptr on the stack will go out of scope and because there's only one reference it will be deleted. You would also need to return a copy not a reference.

You should never return a reference to a stack variable because again, as soon as the function exists it will be deleted.

If you cannot change the return type then the only (icky) option would be to allocate the string on the heap, return a reference to the pointer, and make sure the calling code knows it's a pointer and later deletes it.

E.g.

const std::string& getVal(const std::string &key) {
  return *(new std::string("Something"));
}

// get the val, remember we must delete this pointer!
std::string* pString = &getVal("SomeKey");
delete pString;
like image 37
Andrew Grant Avatar answered Mar 11 '23 23:03

Andrew Grant