string.c_str() troubles

Hi Guys,

I'm having some problems with c_str of the string() method of a boost::filesystem path object.

Can any one explain this please?

1
2
3
4
5
6
7
8
9
path mainCurrFile = path(mainCurrDir) /= *it;
...
...
const char *const fileName = mainCurrFile.string().c_str();
...
...
std::cout << "Delete file " << fileName << std::endl;
std::cout << "Delete file " << mainCurrFile.string() << std::endl;
std::cout << "Delete file " << mainCurrFile.string().c_str() << std::endl;


The first cout, outputs junk. The second two output the correct string.

Interestingly appending the following fails.
1
2
3
4
5
6
...
...
if( fileName == mainCurrFile.string().c_str() )
{
   std::cout << "The same" << std::endl;
}


But, the following works (prints out "The same").
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
path mainCurrFile = path(mainCurrDir) /= *it;
...
...
const char *const fileName = mainCurrFile.string().c_str();
const char *const fileName2 = mainCurrFile.string().c_str();
...
...
std::cout << "Delete file " << fileName << std::endl;
std::cout << "Delete file " << mainCurrFile.string() << std::endl;
std::cout << "Delete file " << mainCurrFile.string().c_str() << std::endl;

if( fileName == mainCurrFile.string().c_str() )
{
   std::cout << "The same" << std::endl;
}


Looking at the buffer addresses it looks like different buffers are being returned on different calls to c_str().

Shouldn't I be able to stash a pointer returned c_str() to use in a later statement?

Many thanks for any help offered,

Cheers,
James
The function mainCurrFile.string() returns a temporary string object, when you call std::string::c_str the returned pointer is granted to hold the right value only until the string object is available, if it get destructed, pointers keeping that location may contain irrelevant values

If you want to get a stable C string, you should copy everything in an array, not just copy the address
Hi Bazzy,

Thanks for your reply... I think I understand now.

Just to double check I get you... the mainCurrFile.string() object is a temporary which will be deconstructed after the line in which it is used?

So would the same apply in the following case?

1
2
3
std::string s("james");
char *name = s.c_str();
std::cout << name << std::endl;


It seems to work so would the difference be that the string class is in scope and valid for the entire block (not temp) and the pointer it returns is to an internally allocated memory block?



Cheers,
James
Yes. As long as the string object is in scope ( and you don't modify it ) the last call to c_str() is granted to have the right value


BTW, here is an example on how to properly get a C string from a C++ string: http://www.cplusplus.com/reference/string/string/c_str/ (lines 13, 14 and 25 of the code example )
Excellent, thanks for the help Bazzy!
Topic archived. No new replies allowed.