#define或char *字符串在哪里驻留在内存中?

时间:2012-12-26 03:42:15

标签: c++ string

  

可能重复:
  Is a string literal in c++ created in static memory?

如果我这样做:
const char* StringPtr = "string0"
那肯定是在记忆中的某个地方,我可以得到StringPtr的地址。

但如果我这样做:
#define STRING0 "string0",那么STRING0所在的位置是什么? 或者,STRING0是否存在于内存中,因为编译器会替换STRING0使用"string0"

据我所知,无论何时在代码中编写任何字符串,编译器都必须将其放在内存中,但我不知道它的确切行为。
但我对此并不十分肯定。

有人可以解释编译器是如何操纵#define编辑或声明为char*的字符串的?

另外,哪一个更好?字符串头文件中的#defineextern const char*extern const std::string

谢谢!

5 个答案:

答案 0 :(得分:5)

在几乎所有情况下,都允许编译器将字符串文字放在任何需要的位置。每次文字出现在源代码中时可能有一个副本,或者在实例之间共享一个主副本。

这会在C中引起麻烦,其中const并不意味着相同的事情,您可以修改内存。在一个平台上,所有相同的字符串都会更改,而在另一个平台上,不会传播。从C ++ 11开始,字符串文字不会隐含地丢失const,并且更难以犯错误。

字符串将在程序启动之前全部初始化,因此它们实际上是可执行二进制映像的一部分。这是肯定的。

这有什么不同:

const char StringPtr[] = "string0",

这定义了一个具有唯一地址的专用数组对象。

答案 1 :(得分:1)

#define STRING0

STRING0不驻留在内存中。它在编译期间甚至不存在。在PRE编译中,STRING0的所有出现都被preprocessor替换为“string0”。在此阶段之后,以下任何阶段或编译的应用程序都不知道名称STRING0

的任何符号的存在

一旦发生这种情况,许多并非所有实例都会以代码中的唯一字符串文字(您的const char*大小写)结束。 @Potatoswatter和@silico提供的link可以更好地回答这些存储在内存中的答案。

答案 2 :(得分:1)

stringPtr驻留在可执行文件的数据部分中。如果您在文本编辑器中打开您的exe,您将能够搜索它。 Data Segment

宏仅在构建程序的预处理阶段持续存在。

根据您的编译器,如果您使用宏方法,您最终可能会在exe中使用相同字符串的几个单独实例,但如果使用char *方法,则只能使用单个实例。

答案 3 :(得分:0)

#define是预处理器宏。在编译代码之前,它将在预编译阶段用STRING0替换"string0"

"string0"驻留在可执行文件的静态只读内存中。

StringPtr是一个变量,这就是你可以获取其地址的原因。它只是指向"string0"的内存地址。

答案 4 :(得分:-1)

当您执行#define时,没有编译器,但预处理器在预先替换为文本“STRING0”中的“string0”处理后的源文件,然后再将其传递给编译器。

编译器从不看到STRING0,但只看到你编写STRING0的“string0”。

编辑:

替换您在源文件中编写的STRING0的每个“string0”实例本身就是字符串文字。如果这些字符串文字保证(或声明)为不变,则编译器可能通过存储这种“string0”和点其它用途实现这一拷贝的单个拷贝优化存储器分配(I改写在编辑本段)。

(编辑:那些相同的文字字符串常量可能会合并为单个副本,但这取决于编译器。标准不要求或强制执行它:http://www.velocityreviews.com/forums/t946521-merging-of-string-literals-guaranteed-by-c-std.html

至于你的上一个问题:最便携的是将它们声明为:const char *

稍后编辑:到目前为止我找到的关于字符串文字的最佳讨论是:https://stackoverflow.com/a/2245983/1284631

另外,请注意字符串文字也可以出现在静态分配的char数组的初始化中,因为它不能与其它副本合并,因为静态数组的内容可能会被覆盖。请参阅下面的示例,其中两个相同的字符串文字“hello”无法合并:

#include <stdio.h>
#include <string.h>

int main(){

        char x[50]="hello";

        printf("x=%s, &x[0]=%p\n",x,&x[0]);

        const char *y="hello";

        printf("y=%s, &y[0]=%p\n",y,&y[0]);

        strcpy(&x[0],"zz");

        printf("x=%s, &x[0]=%p\n",x,&x[0]);

        return 0;
}

此代码的输出为:

x=hello, &x[0]=0x7fff8a964370
y=hello, &y[0]=0x400714
x=zz, &x[0]=0x7fff8a964370