4

可能重复:
C++ 中的字符串文字是在静态内存中创建的吗?

如果我这样做:
const char* StringPtr = "string0"
那么它肯定在内存中的某个地方,我可以得到StringPtr.

但如果我这样做:
#define STRING0 "string0",那么STRING0居住在哪里?
或者,STRING0由于编译器替换使用STRING0by而不存在于内存中"string0"

据我所知,每当您在代码中编写任何字符串时,编译器都必须将其放在内存中的某个位置,但我不知道它的确切行为。
但我对此不太确定。

谁能解释编译器如何操作#define-ed 或声明为的字符串?char*

还有,哪个更好?到#defineextern const char*extern const std::string在字符串的头文件中?

谢谢!

4

5 回答 5

5

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

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

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

有什么不同的是:

const char StringPtr[] = "string0",

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

于 2012-12-26T03:51:30.537 回答
1
#define STRING0

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

一旦发生这种情况,并非所有实例中的许多实例最终都会成为const char*整个代码中的唯一字符串文字(您的情况)。@Potatoswatter 和@silico 提供的链接更好地回答了这些存储在内存中的位置

于 2012-12-26T03:45:02.507 回答
1

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

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

根据你的编译器,如果你使用宏方法,你可以在你的 exe 中得到几个相同字符串的单独实例,但如果你使用 char* 方法,你可以只使用一个实例。

于 2012-12-26T03:51:33.580 回答
0

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

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

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

于 2012-12-26T03:53:16.967 回答
-1

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

编译器永远不会看到 STRING0,而只会在您编写 STRING0 的任何地方看到“string0”。

编辑:

替换您在源文件中编写的 STRING0 的每个“string0”实例本身就是一个字符串文字。如果这些字符串文字被保证(或声明)为不变,那么编译器可能会通过存储此“string0”的单个副本并将其他用途指向该副本来优化内存分配(我在编辑中改写了这一段)。

(编辑:那些相同的文字字符串常量可能会合并到一个单独的副本中,但这取决于编译器。标准不要求或强制执行它: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
于 2012-12-26T03:45:52.810 回答