V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Vibra
V2EX  ›  程序员

求解一个简单的 C 语言的问题, 事实证明我一直是错的

  •  
  •   Vibra · 2020-08-25 14:18:16 +08:00 · 2078 次点击
    这是一个创建于 1553 天前的主题,其中的信息可能已经有所发展或是发生改变。

    直接上代码

    #include <stdio.h>
    
    char *test() {
    //    char res[] = "hello, world";
    //    return res;
        return "hello, world";
    }
    
    const char *tt() {
        const char *str = test();
        printf("%s\n", str);
        return str;
    }
    
    int main() {
        const char *str = tt();
        printf("%s\n", str);
    }
    

    结果是打印了两次 hello world, 注释是两个乱码
    所以, 请问 return “hello, world” 的这个存储 hello, world 的内存在什么地方

    7 条回复    2020-08-26 16:58:21 +08:00
    codehz
        1
    codehz  
       2020-08-25 14:23:59 +08:00   ❤️ 1
    字符串常量区啊
    Vibra
        2
    Vibra  
    OP
       2020-08-25 14:26:50 +08:00
    @codehz 了解了, 之前一直不知道还有这么一个区, 感谢
    junnplus
        3
    junnplus  
       2020-08-25 14:32:48 +08:00
    你给 char res 加一个 static 就可以了,放在静态区
    CismonX
        4
    CismonX  
       2020-08-25 14:33:57 +08:00 via iPhone   ❤️ 3
    字符串字面量一般存储在 .rodata 区段,而用字符串字面量来初始化字符数组时,则会将其拷贝到栈,当然函数返回后栈帧被释放,所以你注释掉的那个返回值其实是一个 dangling pointer
    Vibra
        5
    Vibra  
    OP
       2020-08-25 14:45:32 +08:00
    @junnplus 我不知道的是还有字符串常量区, 这样可以不用加 static
    akatquas
        6
    akatquas  
       2020-08-25 17:57:05 +08:00   ❤️ 3
    你找个编译成汇编的工具,一目了然。

    常量字符串在 c 里面是有优化存储的。
    甚至你`"%s\n"`这字符串也可以被存到了这个地方,取决于编译器行为。
    推荐一个网站,https://godbolt.org/
    Vibra
        7
    Vibra  
    OP
       2020-08-26 16:58:21 +08:00
    @akatquas 很有用, 感谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3067 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 14:24 · PVG 22:24 · LAX 06:24 · JFK 09:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.