C lines vs const char * bothers me ... help please

I'm starting C / C ++, trying to create something that seems like a fairly simple program: it loads the file into a c-line (const char *). However, although the program is incredibly simple, it does not work as I understand it. Take a look:

#include <iostream> #include <fstream> std::string loadStringFromFile(const char* file) { std::ifstream shader_file(file, std::ifstream::in); std::string str((std::istreambuf_iterator<char>(shader_file)), std::istreambuf_iterator<char>()); return str; } const char* loadCStringFromFile(const char* file) { std::ifstream shader_file(file, std::ifstream::in); std::string str((std::istreambuf_iterator<char>(shader_file)), std::istreambuf_iterator<char>()); return str.c_str(); } int main() { std::string hello = loadStringFromFile("hello.txt"); std::cout << "hello: " << hello.c_str() << std::endl; const char* hello2 = loadCStringFromFile("hello.txt"); std::cout << "hello2: " << hello2 << std::endl; hello2 = hello.c_str(); std::cout << "hello2 = hello.c_str(), hello2: " << hello2 << std::endl; return 0; } 

The result is as follows:

 hello: Heeeeyyyyyy hello2: 青! hello2 = hello, hello2: Heeeeyyyyyy 

The initial value of hello2 changes every time, always some kind of random kanji (I use a Japanese computer, so I suppose it's somehow kanji).

In my naive view, it seems that two values ​​should print the same way. One function returns a C ++ string, which is then converted to a c-string, and the other loads the string, converts the c-string from it, and returns it. I made sure that the line loaded properly in loadCStringFromFile by subtracting the value before I returned it, and indeed it was what I thought, for example:

 /*(inside loadCStringFromFile)*/ const char* result = str.c_str(); std::cout << result << std::endl;//prints out "Heeeyyyyyy" as expected return result; 

So why should the value change? Thanks for the help...

+4
source share
3 answers

function

 std::string loadStringFromFile(const char* file) 

returns a string copy of the string created inside the function, which is copied before the string goes beyond the scope, that is, the function ends, so it works.

 const char* loadCStringFromFile(const char* file) 

on the other hand, it returns a pointer to a local string that goes beyond the scope when the function returns and is destroyed, so the returned address const char* points to an undefined location.

for the second method to work, you need to create a line before calling the function:

 const char* loadCStringFromFile(const char* file, string& str); // return str.c_str() .. string str; const char* result = loadCStringFromFile(file,str); 

or you create a line on the heap in a function and pass the address back, but this becomes a bit messy, as the caller will need to delete the line to avoid memleak.

+3
source

Your problem is that str in loadCStringFromFile is a local variable and is destroyed when the function returns. At this point, the invalid return value from c_str() .

More here

Your first function, loadStringFromFile , is a more C ++-like way to execute it and illustrates the advantage of using class management memory. If you use char *, you need to pay much more attention when memory is allocated and freed.

+4
source

You should duplicate the output of str.c_str ():

 return strdup(str.c_str); 

The strdup function can be found in the cstring header.

-1
source

All Articles