字符串字面量是在堆栈上创建的吗?

4

对于这个表达式,我有点困惑:

char *s = "abc";

字符串字面量是在堆栈上创建的吗?

我知道这个表达式

char *s = (char *)malloc(10 * sizeof(char));

在堆上分配内存,这个表达式

char s[] = "abc";

在堆栈上分配内存,但我完全不确定第一个表达式的作用。

3个回答

21

通常情况下,字符串字面量"abc"将被存储在可执行文件的只读部分。指针s将在栈上创建(或放置在寄存器中,或仅进行优化)- 并指向那个生存在“其他地方”的字符串字面量。


1
请注意,即使s是char而不是char const,您也无法可移植地修改字符串“abc”。 - AProgrammer
实际上,使用char *引用只读常量被认为是不推荐的。编译器也会发出警告。新软件应该使用const char *。 - Thorsten79
可执行文件除了“可执行文件的只读部分”之外还有其他部分吗?也许“只读内存”会更清晰一些。 - alexkr
@AlexKR:这要看情况。从大多数加载器的角度来看,“可执行文件的部分”是代码段和数据段。一些数据段是只读的(例如包含字符串文字),而其他数据段是可读写的(包含非常量静态变量)。当然,这都是与平台相关的,但总的来说,如果您认为RO数据是“可执行文件的一部分”,那么您也可以认为RW数据是一部分。 - Steve Jessop

6
"abc"

如果启用了字符串池化,字符串字面量将存储在程序的__TEXT,__cstring(或rodata或取决于对象格式的其他地方)部分。这意味着它既不在堆栈上,也不在堆中,而是停留在靠近代码的只读内存区域。

char *s = "abc";

这个语句将会把字符串常量"abc"的内存位置赋给变量s,也就是说,s指向一个只读内存区域。

3
"堆栈"和"堆"是实现细节,取决于平台(全世界不只有x86)。从语言角度来看,重要的是存储类别和范围。
字符串文字具有静态范围;它们的存储空间在程序启动时分配并持续到程序终止。还假设字符串文字无法修改(尝试这样做会调用未定义的行为)。与局部、块作用域(自动)变量相比,后者的存储空间在块输入时分配,块结束时释放。通常,这意味着字符串文字不会存储在与块作用域变量相同的内存中。"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接