Overview
Features
Download
Documentation
Community
Add-Ons & Services

NameValuePair::get() and string literals crash

Please post support and help requests here.

NameValuePair::get() and string literals crash

Postby budric » 13 Jun 2013, 00:36

Hi,

The I am getting a segfault on linux around the area of HTMLForm::get(). I say around because it doesn't crash on this call specifically but later on when I start using the values. Here's my code
Code: Select all
const string & myBoolean = form.get("key", "false");

If I remove that line of code the segfault goes away.

I looked at your implementation
Code: Select all
const std::string& NameValueCollection::get(const std::string& name, const std::string& defaultValue) const
{
   ConstIterator it = _map.find(name);
   if (it != _map.end())
      return it->second;
   else
      return defaultValue;
}


I think if I pass a string literal such as "false", this will create a temporary defaultValue on the stack, and then return a reference to that value which is invalid. Is the function not meant to be used this way? In that case the defaultValue should be std::string & (without const) to not allow users to pass string literals. Or the return value should be std::string not a reference - in which case it will be a bit slower.

But it doesn't seem right to me. Any confirmation? Comments?

Thanks.
budric
 
Posts: 24
Joined: 13 May 2009, 17:14

Re: NameValuePair::get() and string literals crash

Postby guenter » 13 Jun 2013, 06:03

The compiler will generate a temporary std::string for the default value ("false"), which will go away after the assignment is done. Assign the result to a std::string and not a const std::string& and it will work.
guenter
 
Posts: 1110
Joined: 11 Jul 2006, 16:27
Location: Austria

Re: NameValuePair::get() and string literals crash

Postby budric » 13 Jun 2013, 16:36

You are right that using std::string in my case and not a reference works. Is it working as it's supposed to, or just luck of the draw?

Is the temporary variable for string literal located after the frame pointer on the stack or before? If the following sequence of steps is correct, I don't see how it works
- Function ends.
- Return value is assigned to return variable reserved on the stack before frame pointer. I assume the allocated return variable is just an address not a string object since you are returning a reference.
- All values are popped of the stack up to the frame pointer. Including the temporary one for string literal I assume?
- Execution returns to old function
- Value is copied from return variable on the stack to local variable. But those objects have been popped of the stack? It's probably still in memory as nobody has messed with the stack up to that point, but technically is the return variable is pointing to invalid data?

Thanks.
budric
 
Posts: 24
Joined: 13 May 2009, 17:14

Re: NameValuePair::get() and string literals crash

Postby guenter » 13 Jun 2013, 17:39

See this StackOverflow topic for background: http://stackoverflow.com/questions/1837 ... expression

Basically, the (simplified) sequence is:
1. for the string literal, a temporary std::string object will be created.
2. the function is called with the temporary std::string object.
3. any other subexpressions on the right side of the assignment will be evaluated.
4. the result will be assigned.
5. the temporary std::string will be destroyed.

So this is safe, as long as you don't use the result to initialize a reference.
guenter
 
Posts: 1110
Joined: 11 Jul 2006, 16:27
Location: Austria

Re: NameValuePair::get() and string literals crash

Postby budric » 14 Jun 2013, 01:40

Thanks
budric
 
Posts: 24
Joined: 13 May 2009, 17:14


Return to Support

Who is online

Users browsing this forum: No registered users and 1 guest

cron