0

This is a portion of my simple program

string appData = getenv("APPDATA");
const char *mypath= (appData+"\\MyApplication\\hello.txt").c_str();      
cout << mypath;  
// output: c:\users\xrobot\appdata\Roaming\Myapplication\hello.txt   
fstream file(mypath,ios::in);
ofstream filetemp;    
filetemp.open("world.bak");
cout << mypath;  
// output: É↕7

Why is mypath changed in that weird string ?

xRobot
  • 25,579
  • 69
  • 184
  • 304
  • 5
    I am surprised that this code compiles. you are treating a cstring like a std::string. – SuperJames Apr 20 '12 at 16:15
  • 1
    If you get the output "c:\users\xrobot\appdata\Roaming\Myapplication\hello.txt" in line 4, I don't believe the snippet here is the actual code you are running. Rather, I would expect a compiler error on the second line. Can we see the actual code? From the symptoms you give, I suspect in your real code you are calling c_str() on a std::string and retaining the returned pointer while leaving the scope the std::string was declared in. Don't do that, hang on to the std::string instead. – moonshadow Apr 20 '12 at 16:17

3 Answers3

7

You should use std::string as:

std::string appData = getenv("APPDATA");
std::string path = appData+"\\MyApplication\\hello.txt";

then do this:

const char * mypath = path.c_str();

Note that you must not do this:

const char* mypath = (appData+"\\MyApplication\\hello.txt").c_str();

It is because expression on the right hand side is a temporary which gets destroyed at the end of the expression and mypath will continue to point to the destroyed object. It becomes a dangling pointer, in other words.

--

Why is mypath changed in that weird string ?

Because in your posted code, mypath is a dangling pointer, using which invokes undefined behavior.

This is how you should write the code:

std::string appData = getenv("APPDATA");
std::string mypath= appData+"\\MyApplication\\hello.txt";
cout << mypath;  
fstream file(mypath.c_str(),ios::in);
Nawaz
  • 353,942
  • 115
  • 666
  • 851
5

You can't add two strings like that. You should receive a clear warning. Since you're using C++, you may want to use std::string instead.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
2

This is just a temporary std::string:

(appData+"\\MyApplication\\hello.txt")

So the underlying C string space can be freed after the expression is used. Since you have a char* pointing to what's now garbage memory, you have a funky value.

chrisaycock
  • 36,470
  • 14
  • 88
  • 125