You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中char* str1 = "Hello world"的字符串与指针存储位置查询

解答

你需要先拆分两个完全独立的存储对象:指针str1本身,以及它指向的字符串字面量"Hello world",二者的存储区域并不相同:

  • 指针str1的存储位置和它的声明作用域直接相关:如果这行代码定义在函数内部,它属于局部变量,存储在栈上;如果定义在函数外部作为全局变量,它会存储在全局/静态存储区。
  • 你调试时发现既不在堆也不在栈上的是"Hello world"字符串本身,它存储在进程地址空间的只读数据段(.rodata 段),属于程序静态存储区的一部分。这块区域的内容是编译器在编译阶段就写入可执行文件的,程序启动加载时由操作系统直接映射到内存,不需要你在代码中手动申请分配,所以你可以直接通过指针读取到字符串内容。

你教授的说法和实际运行效果并不矛盾:

你教授提到的「没有为str1分配可指向的内存」,实际指的是你没有主动分配可写的内存给str1指向:.rodata 段的内存属性是只读的,如果你尝试通过str1修改字符串中的字符(比如执行str1[0] = 'h'),会直接触发段错误导致程序崩溃。C++标准把char*直接指向字符串字面量的写法标记为弃用,本质就是为了避免开发者误以为这段内存可写,引发无预警的运行时错误。符合规范的写法应该是const char* str1 = "Hello world";,从语法层面就禁止对指向内容的修改操作。

如果你想自行验证变量的内存位置,在Linux环境下可以通过以下方法操作:

  1. 打印不同存储类型变量的地址对比,参考测试代码:
#include <iostream>
#include <cstdlib>
using namespace std;

int global_test_var;

int main() {
    int stack_test_var;
    int* heap_test_var = new int;
    const char* str_test = "Hello world";

    cout << "全局变量地址:" << &global_test_var << endl;
    cout << "栈局部变量地址:" << &stack_test_var << endl;
    cout << "堆变量地址:" << heap_test_var << endl;
    cout << "字符串字面量地址:" << (void*)str_test << endl;
    cout << "指针str_test本身的地址:" << &str_test << endl;

    delete heap_test_var;
    return 0;
}

运行后你可以直观看到,字符串字面量的地址和全局变量的地址区间接近,和栈、堆的地址区间都有明显差异。
2. 编译得到可执行文件后,执行readelf -S 你的可执行文件名命令查看段信息,可以直接看到.rodata段的地址范围,和你打印的字符串字面量地址完全匹配。

内容的提问来源于stack exchange,提问作者JAYD3V

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 02:27:02