1

I wrote a function called ws2s to convert wstring to string:

std::string ws2s(const std::wstring & src)
{ 
   std::string res = "";

   size_t const mbs_len = wcstombs(NULL, src.c_str(), 0);

   std::vector<char> buffer(mbs_len + 1);

   wcstombs(&buffer[0], src.c_str(), buffer.size());

   res.assign(buffer.begin(), buffer.end() - 1);

   return res;
}

I use valgrind to run for memory check got some error. There is any difference between these two ways to call function ws2s?

First method:

std::string xml_path = ws2s(something);
const char * path = xml_path.c_str();

Second method:

const char * path = ws2s(something).c_str();
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
J.Doe
  • 319
  • 1
  • 8
  • The code you show is clearly C++, so why did you add the C language tag? – Some programmer dude Feb 11 '19 at 06:55
  • And when asking about "errors", always include the actual errors. Copy-pasted as text, in full and complete. And don't forget to also include the [mcve] that generates the error. Please take some time to read about [how to ask good questions](http://stackoverflow.com/help/how-to-ask), as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Feb 11 '19 at 06:56
  • @Someprogrammerdude valgrind errors seems too long,and the code have 6k line,no one want to read it. – J.Doe Feb 11 '19 at 06:58
  • @J.Doe - You are correct that no one wants to read 6k lines, that's why you were pointed to the **Minimal**, Complete and Verifiable example page to learn how to make a good one. – StoryTeller - Unslander Monica Feb 11 '19 at 07:00
  • That's why you should create a [***Minimal***, Complete, and Verifiable Example](https://stackoverflow.com/help/mcve) to show us. One that exhibits the problem but doesn't generate more than the bare minimum error output needed to diagnose the problem. Often when creating such an example, you might even figure out the problem and the solution yourself. – Some programmer dude Feb 11 '19 at 07:02
  • @Some programmer dude: To be fair, his minimal example already points out very well the mistake. – user826955 Feb 11 '19 at 07:12
  • 1
    @slawekwin thanks ,It's the same question. – J.Doe Feb 11 '19 at 09:46

2 Answers2

4

In the first method you call the function and assign the result to a local variable. Then you get the pointer to the data held by the string object. This is all fine and the proper way to do this.

In the second method you call the function and assign to a variable a pointer to the data held by the temporary result object. The temporary object is then destroyed at the end of the full expression, freeing the data pointed to by your variable. This creates a dangling pointer, whose dereference causes undefined behavior.

You may use such syntax if you need to use the pointer only before the end of the expression (without copying it), e.g.:

std::strcmp(ws2s(something).c_str(), "test");
slawekwin
  • 6,270
  • 1
  • 44
  • 57
2

In the second example, the temporary object (return value of ws2s) is destroyed after the call to .c_str(), thus your pointer in path becomes invalid.

In the first example, of course, this is not the case, and the pointer will be valid as long as you keep xml_path.

user826955
  • 3,137
  • 2
  • 30
  • 71