这些对get_string和get_string2的调用都会返回在函数返回时超出范围的对象.返回的对象不应该是函数返回后超出范围的内存中的地址吗?这是使用Visual Studio 2008.这总是有效吗?为什么?
#include <iostream>
enum myID { SMALL, MEDIUM, LARGE };
const char* get_string(myID id) {
switch(id){
case SMALL: return "small";
case MEDIUM: return "medium";
case LARGE: return "large";
default: return "unknown";
}
}
const char* get_string2(myID id) {
char* s = 0;
switch(id){
case SMALL: s = "small"; return s;
case MEDIUM: s = "medium"; return s;
case LARGE: s = "large"; return s;
default: return "unknown";
}
}
int main() {
std::cout << get_string(SMALL) << std::endl;
std::cout << get_string2(SMALL) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Arm*_*yan 11
字符串文字是唯一的左值文字,具有静态存储持续时间.因此,返回指向字符串文字的第一个元素的指针是非常安全的.相比
const char* f1()
{
return "Hello"; // OK
}
const char* f2()
{
const char s[6] = "Hello";
return s; // Undefined Behavior
}
const char* f3()
{
const char* s = "Hello";
return s; //OK
}
Run Code Online (Sandbox Code Playgroud)
从评论来看,这个答案需要一些阐述.好的,看,字符串文字存储在内存中,直到程序完成.在案例1中,您返回指向它的指针.对象指针是活着的,所以没关系.在案例3中,您将文字的地址转换为局部变量s并通过复制返回后者.地址的副本仍然指向有效的内存,所以没关系.但是,在第二种情况下,我们将字符串文字复制到本地数组中,该数组在函数退出时被销毁.返回局部变量的地址是未定义的行为.
此外,如果你认为是未定义行为是确切定义,那么你不应该感到惊讶是因为未定义行为可能意味着
所以如果有效的话并不意味着没关系.在这种情况下,它是,但不是在一般情况下.