最近我看了一个人的代码,发现编译器对以下代码没有任何抱怨,也没有运行时错误:
const char *p = "I didn't malloc...";
上面的代码是有效的,但我想知道它是如何工作的。这是我认为正在发生的事情。有人可以确认一下吗?
所以,“我没有malloc…”在编译时静态地分配在堆栈上,并将该地址传递给指针p。类似于静态数组的分配方式。我90%确定这一点,但一些确认会有所帮助。
谢谢。
p
指向的只读内存中有一个字符串文字 "I didn't malloc..."
(确切的位置是由实现定义的)。const
限定符,例如:const char *p = "I didn't malloc...";
这是一个字符串字面量。标准并不知道什么是"堆栈"等 - 这些都是实现细节。所以没有"标准"位置。
但通常不在堆栈上。它在一个只读区域中,称为text
。它也不是"类似于静态数组的分配方式"。
data
是用于可写的已初始化的东西。 - cnicutar内存通常被分配为只读的,任何试图更改 *p 的尝试都是未定义的。
不过,这种分配的内存通常不在堆栈上,而是成为可执行文件的数据段的一部分。
字符串字面量"I didn't malloc..."
被存储在数据段的只读区域中,而p
包含该位置的地址。
p将指向在堆栈上分配的只读内存区域。 此外,编译器会自动在字符串末尾添加'\0'字节以进行空值终止。
不使用const是危险的,事实上g++编译器会对以下代码发出警告:
#include <stdio.h>
int main(int argc, const char *argv[])
{
char *p = "AString8";
printf("%s\n", p);
printf("Last char: %c hex: %x\n", p[7], p[7]);
printf("Last char + 1: %c hex: %x\n", p[8], p[8]);
return 0;
}
警告:从字符串常量转换为'char *'已被弃用
程序输出:
Last char: 8 hex: 38
Last char + 1: hex: 0
p
的类型应该是char const *
,因为该数据段(“通常”)不可写,现今大多数编译器都会发出警告。 - Filip Roséen - refpconst char *
,所以这一行应该是“赋值丢弃限定符”的错误。 - Danielchar const*
自动转换为char*
的情况(以允许与C的向后兼容性)。我认为这在C++11中已被弃用。但大多数编译器会产生警告。 - Martin York