I know this is valid in C++, because temporary from std::string("xxx")
lives to the end of the full expression it appears in.
printf("%s\n", std::string("xxx").c_str());
And this is valid too:
std::string f1() {
return std::string("xxx");
}
void g1() {
printf("%s\n", f1().c_str());
}
But is this valid? if not, why?
const char* f2() {
return std::string("xxx").c_str();
}
void g2() {
printf("%s\n", f2());
// or: std::string x = f2(); // is this valid?
}
The temporary std::string
inside of f2
is destroyed when the function returns. The char*
will be dangling.
EDIT: In response to the comment, std::string x = f2()
is also not valid. It's still bad to initialize a std::string
from a dangling pointer.
The exact same rule applies. The full-expression in which the std::string
was created in f2
is
std::string("xxx").c_str()
together with the construction of the return value from it.
After this expression executed and the construction of the return value executed, the temporary std::string("xxx")
will be destroyed. Since destruction of the temporary std::string
makes the const char*
obtained from .c_str()
and copied into the return value invalid, the return value of the function cannot be used in any way.
For f1
the same applies (details relating to temporary materialization and copy elision, especially in C++17, aside). The temporary std::string
is destroyed after construction of the return value. But in this case this is not a problem, because the return value is not a pointer to something that was destroyed, but an independent std::string
object itself. This std::string
object will live until the end of the full-expression in which the call to f1
appears, ie until the end of
printf("%s\n", f1().c_str())
The following would be fine as well:
std::string f3() {
return std::string("xxx").c_str();
}
Here again, a new std::string
is created in the return value, which will live until the end of the full-expression in which f3
is called.
In practice, for f1
, since std::string("xxx");
is already a prvalue of type std::string
, copy elision will be applied, so that there is really only one temporary object, the return value of f1
. The intermediate temporary will be eliminated and the return value directly constructed from "xxx"
. This is mandatory since C++17 and was allowed and common before C++17.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.