Originally Posted by
R_W_B
In essence the memory of the returned ptrs (or reference) of any of the above calls is valid until the return completion only.
And whatever stores or grabs that returned ptr needs to immediately copy the value of what's pt'd to, since in the near future depending on happenstance that memory pt'd to may have something different in it. Correct ?
We need to separate locals and temporaries.
For example, My_SS.str() returns a temporary. The object returned by this function will be destroyed once the line has finished executing. So if we want to store the object for later use, we have to store it in a local variable, which we can do with:
auto MyS = My_SS.str();
MyS will live until the end of the local scope, but the object returned by My_SS.str() will only live until the end of the above line.
Let's take a break and explain 2):
(2) Also something that confuses me somewhat (at my point of traverse in C++) is when I look at class references of stringstream class I don't see any members, functions or references to the c_str() function. Is the stringstream str() able to call c_str() because of the inheritance thing ? (I'm still learning the aspects of inheritance).
A stringstream has no c_str() function. The stringstream returns a temporary std::string object when you call str(). The compiler, in turn, invokes c_str() on this temporary object. If you look at the documentation for std::string, you'll notice it's there. This has nothing to do with inheritance. In pseudo code, you might visualise at as:
Code:
auto MyStr = MyStringStream.str();
auto MyPointer = MyStr.c_str();
MyStr.Destroy();
So let's go back to 1). In the above code, you will notice that the temporary string object is destroyed. The memory pointed to by MyPointer belongs to the temporary string object. When it is destroyed, it releases that memory. Accessing freed memory is undefined behaviour - the standard doesn't say what will happen. In practice, you may get an access violation or read some junk or the original data may still be there (but the OS is free to reuse it).
Therefore,
Code:
const char* p_My_Str = My_SS.str().c_str();
is wrong, because p_My_Str points to freed memory.
Code:
ofstream ofstr_ReVest(ssName.str().c_str());
This is okay, because the memory pointed to by c_str() will only be freed after the current line has finished executing because that's when the temporary string created will be destroyed.
Code:
string My_S;
My_S = My_SS.str();
const char* p_My_S = My_S.c_str();
This is also okay because My_S is a local variable and will only be destroyed when the local scope ends.
Code:
ofstream ofstr_ReVest(ssName.str());
This is also okay because the temporary returned string object will be alive until the end of the line.
(3) And not with standing the answer of (2) how would a compiler setting make possible for this, ofstream ofstr_ReVest(ssName.str());
to happen when the c_str() is just left off. Is this some sort of promoted call or overloaded call ? Sorry if my nomenclature labels are mangled, but hopefully I've gotten the premise of my questions clear.
fstream have an overloaded constructor that takes an std::string.
(4) And finally is the std::strcpy( .., ..) the same strcopy that I read in some dated articles that everyone stopped using it some yrs back because of it being susceptible to buffer overflow hacks? Seems they were promoting a new strncopy lib or something like that.
Or is std::strcpy still considered safe to use in code?
std::strcpy is fine if you use it right. But that's risky since one tend to make mistakes. std::strncpy is just another version that says copy max N characters. It's safer than std::strcpy, but just as unsafe if you pass in the incorrect arguments. It is much safer to simply use std::string.