在c ++中存储文字常量

时间:2017-04-17 15:31:08

标签: c++

我想知道文字常量实际存储在内存中的哪个位置?

示例:

int i = 5;
char* data = char* &("abcdefgh");

idata的存储部分取决于它们的声明位置。 但是,在将实际复制到变量之前,编译器是否存储5"abcdefgh"

在这里,我可以获取存储它的"abcdefgh"地址,但为什么我无法获得5的地址?

3 个答案:

答案 0 :(得分:9)

5之类的整数文字可以作为机器指令的一部分。例如:

 LD A, 5
对于某些虚构架构,

会将值5加载到处理器寄存器A中,并且由于5实际上是指令的一部分,因此它没有地址。很少(如果有的话)架构能够在机器指令中内联创建字符串文字,因此这些架构必须实际存储在内存中的其他地方并通过指针访问。究竟在哪里"其他地方"未被C ++标准指定。

答案 1 :(得分:6)

在语言层面,字符串文字和数字文字是不同的野兽。

C和C ++标准基本上指定字符串文字被处理"好像"您定义了具有适当大小和内容的常量字符数组,然后使用其名称代替文字。 IOW,当你写的时候

const char *foo = "hello";

它的好像是你写的

// in global scope
const hello_literal[6] = {'h', 'e', 'l', 'l', 'o', '\0'};

...
const char *foo = hello_literal;

(有一些向后兼容性的例外情况,您甚至可以在没有char *foo = "hello";的情况下编写const,但是不赞成这种情况,并且无论如何都要尝试将其定义为未定义的行为通过这样的指针写)

所以,鉴于这种等价,你可以拥有字符串文字的地址是正常的。整数文字OTOH是 rvalues ,标准规定你不能接受任何地址 - 你可以粗略地认为它们是标准期望在常规意义上没有后备存储位置的值

现在,这种区别实际上源于在机器级别它们通常以不同方式实现。

字符串文字通常在内存中的某处存储作为数据,通常位于只读数据部分中,该部分直接从可执行文件映射到内存中。当编译器需要它的地址时,很容易理解,因为它是已经在内存中的数据内容,因此它确实有地址。

相反,当您执行类似

的操作时
int a = 5;

5并没有像上面"hello world"数组那样的单独内存位置,但它通常作为立即值嵌入到机器代码中

指向它的指针非常复杂,因为它是一个指向指令中途的指针,并且通常以不同于常规{{1}的预期格式指向数据一些你可以指出的变量 - 想想x86在哪里为小数字你使用更紧凑的编码,或者PowerPC / ARM和其他RISC架构,其中一些值是由一个由隐式桶形移位器操纵的直接构建的,你甚至不能为某些人提供立即数据值 - 你必须用几个指令组成它们,或者哈佛架构,其中数据和代码存在于不同的地址空间中。

因此,您不能获取数字文字的地址(以及数字表达式评估结果和许多其他临时内容);如果你想拥有一个数字的地址,你必须先将它分配给一个变量(可以提供内存存储),然后询问它的地址。

答案 2 :(得分:3)

尽管C和C ++标准没有规定文字的存储位置,但是常见的做法是将它们存储在以下两个地方之一:代码中(参见@NeilButterworth答案)或者#34;常量&# 34;分割。

常见的可执行文件包含代码部分和数据部分。数据段可以分成只读,未初始化的读/写和初始化的读写。通常,文字放在可执行文件的只读部分。

某些工具也可能将文字放入单独的数据文件中。该数据文件可用于将数据编程为只读存储器设备(ROM,PROM,Flash等)。

总之,文字的位置取决于实现。 C和C ++标准规定写入文字位置是未定义的行为。使用字符文字的首选做法是将变量声明为const,以便编译器在写入文字时可能会生成警告或错误。