const char *fun1()
{
const char *a = "hello";
return a;
}
const char *fun2()
{
const char a[] = "hello";
return a;
}
int main(int argc, char *argv[])
{
printf("%s\n", fun1());
printf("%s\n", fun2());
return 0;
}
输出:
cpp:12:12: warning: address of local variable 'a' returned [-Wreturn-local-addr]
12 | return a;
| ^
passwords.cpp:11:16: note: declared here
11 | const char a[] = "hello";
| ^
hello
(null)
这两种分配字符串的方法有什么区别? 我收到一个警告而另一个没有? 我知道当我们从函数返回时局部变量会被破坏,但为什么 fun1() 不是这种情况? 它是否在其他地方而不是堆栈中获得内存?
答案 0 :(得分:4)
在您的情况下,fun1()
中字符串的字节存在于静态内存中。在另一个函数中,字节在初始化时从静态内存复制到堆栈上的缓冲区中。访问从fun2()
返回的返回字符串是未定义的,因为堆栈上的数组不再存在。
fun1()
可以改写为
const char fun1()
{
static const char s[] = "hello";
const char* a = s;
return a;
}
fun2()
可以改写为
const char fun2()
{
static const char s[] = "hello";
const char a[6]; // stack allocation (5 letters + 1 zero terminator)
strcpy(a, s);
return a; // UB: return pointer to local automatic array
}
所以你得到警告的主要原因是调用后 fun2()
中的数组不存在。你返回一个指针到栈帧中,同样的方式下面的代码也有同样的问题:
struct S { int x, y; };
struct S* fun1()
{
static struct S s = { 10, 42 };
return &s; // no problem
}
struct S* fun2()
{
struct S a = { 10, 42 };
return &a; // UB
}