这是一个非常经典的 C 语言问题,涉及到字符串常量和数组的内存分配。
代码如下:
int main()
{
char buf[] = "hello";
fun(buf);
return 0;
}
你问的是:“内存中一共有两个 hello
吗?”
🔍 分析内存情况
char buf[] = "hello";
这个声明做了两件事:
-
在栈(stack)中创建了一个字符数组
buf
,长度是 6 个字节(包括\0
结尾符)。 -
把字符串常量
"hello"
的内容 复制 到这个数组里。
字符串常量 "hello"
在编译时,字符串常量 "hello"
被保存在只读数据段(.rodata 段)。这是 只读内存区,它里面的 "hello"
是不可修改的。
✅ 结论:是的,内存中会有两个 "hello"
位置 | 内容 | 可修改性 |
---|---|---|
栈内存 | buf[] | ✅ 可修改 |
只读段 | "hello" | ❌ 不可修改 |
📌 图示说明(逻辑结构)
内存:
[.rodata] --> "hello\0" (只读字符串常量)
[stack - buf[]] --> 'h' 'e' 'l' 'l' 'o' '\0' (可修改的局部数组)
⚠️ 注意事项
-
如果你写的是
char *buf = "hello";
,那就不会复制字符串,而是直接让buf
指向只读段中的"hello"
。 -
在那种情况下,只有一个
"hello"
存在于内存中,而且不能修改它。
示例对比
char buf[] = "hello"; // ✅ 会复制字符串,有两个 "hello"
char *buf = "hello"; // ❗ 只有一个 "hello",在只读区
需要我帮你画出完整的内存图吗?可以让你更直观地理解。