c++ - const char *p = "some_string"和 const char[] = "some_string"在内存分配方面的区别

标签 c++ c c-strings

<分区>

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() 不是这种情况? 它是否在其他地方而不是堆栈获取内存?

最佳答案

在您的例子中,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
}

关于c++ - const char *p = "some_string"和 const char[] = "some_string"在内存分配方面的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65655119/

相关文章:

c++ - 二进制文件不能多次使用?

c - 斐波那契数列之和

c - 为什么 strlen 在 C 中导致段错误?

c - 打印最后没有填充 0 的字符串

c++ - 体系结构 x86_64 "_SDL_Init"的 undefined symbol

c++ - 在 OpenCv C++ 中使用原始图像作为掩码从图像中删除 Logo

c++ - 在 Windows/Visual Studio 上用 C++ 在运行时编译函数的简单有效的方法是什么?

检查文件是否是C中的特定类型

python - 如何使用 twenacl 交换和验证临时公钥?

c++ - 同时交换 char 数组中的多个对象