const char *p = "some_string" 和 const char[] = "some_string" 在内存分配方面的区别
Difference between const char *p = "some_string" and const char[] = "some_string" in terms of memory allocation
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)
这两种分配字符串的方法有什么区别?
我收到一个警告而不是另一个警告?
我知道当我们从函数中 return 时局部变量会被破坏,但为什么 fun1() 不是这种情况?
它是否在其他地方而不是堆栈获取内存?
在你的例子中,fun1()
中字符串的字节存在于静态内存中。在另一个函数中,字节在初始化时从静态内存复制到堆栈上的缓冲区中。访问从 fun2()
编辑 return 的 returned 字符串是未定义的,因为堆栈上的数组不再存在。
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()
中的数组在调用后不存在。你return一个指向栈帧的指针,同理下面的代码也有同样的问题:
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
}
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)
这两种分配字符串的方法有什么区别? 我收到一个警告而不是另一个警告? 我知道当我们从函数中 return 时局部变量会被破坏,但为什么 fun1() 不是这种情况? 它是否在其他地方而不是堆栈获取内存?
在你的例子中,fun1()
中字符串的字节存在于静态内存中。在另一个函数中,字节在初始化时从静态内存复制到堆栈上的缓冲区中。访问从 fun2()
编辑 return 的 returned 字符串是未定义的,因为堆栈上的数组不再存在。
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()
中的数组在调用后不存在。你return一个指向栈帧的指针,同理下面的代码也有同样的问题:
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
}