C语言 字符串文字:它们去哪里了?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2589949/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:05:31  来源:igfitidea点击:

String literals: Where do they go?

cmemorystring-literals

提问by Chris Cooper

I am interested in where string literals get allocated/stored.

我对分配/存储字符串文字的位置感兴趣。

I did find one intriguing answer here, saying:

我确实在这里找到了一个有趣的答案,他说:

Defining a string inline actually embeds the data in the program itself and cannot be changed (some compilers allow this by a smart trick, don't bother).

定义一个内联字符串实际上是将数据嵌入到程序本身中并且无法更改(有些编译器通过一个聪明的技巧允许这样做,不要打扰)。

But, it had to do with C++, not to mention that it says not to bother.

但是,它与 C++ 有关,更不用说它说不要打扰。

I am bothering. =D

我很烦。=D

So my question is where and how is my string literal kept? Why should I not try to alter it? Does the implementation vary by platform? Does anyone care to elaborate on the "smart trick?"

所以我的问题是我的字符串文字在哪里以及如何保存?为什么我不应该尝试改变它?实施是否因平台而异?有人愿意详细说明“聪明的把戏”吗?

采纳答案by R Samuel Klatchko

A common technique is for string literals to be put in "read-only-data" section which gets mapped into the process space as read-only (which is why you can't change it).

一种常见的技术是将字符串文字放入“只读数据”部分,该部分以只读方式映射到进程空间(这就是您无法更改它的原因)。

It does vary by platform. For example, simpler chip architectures may not support read-only memory segments so the data segment will be writable.

它确实因平台而异。例如,较简单的芯片架构可能不支持只读存储器段,因此数据段将是可写的。

Rather then try to figure out a trick to make string literals changeable (it will be highly dependent on your platform and could change over time), just use arrays:

与其尝试找出使字符串文字可变的技巧(它将高度依赖于您的平台并且可能会随着时间的推移而改变),只需使用数组:

char foo[] = "...";

The compiler will arrange for the array to get initialized from the literal and you can modify the array.

编译器将安排从文字初始化数组,您可以修改数组。

回答by Jerry Coffin

There is no one answer to this. The C and C++ standards just say that string literals have static storage duration, any attempt at modifying them gives undefined behavior, and multiple string literals with the same contents may or may not share the same storage.

对此没有一个答案。C 和 C++ 标准只是说字符串文字具有静态存储持续时间,任何修改它们的尝试都会产生未定义的行为,并且具有相同内容的多个字符串文字可能会或可能不会共享相同的存储空间。

Depending on the system you're writing for, and the capabilities of the executable file format it uses, they may be stored along with the program code in the text segment, or they may have a separate segment for initialized data.

根据您编写的系统及其使用的可执行文件格式的功能,它们可能与程序代码一起存储在文本段中,或者它们可能有一个单独的段用于初始化数据。

Determining the details will vary depending on the platform as well -- most probably include tools that can tell you where it's putting it. Some will even give you control over details like that, if you want it (e.g. gnu ld allows you to supply a script to tell it all about how to group data, code, etc.)

确定细节也将因平台而异——很可能包括可以告诉您将它放在哪里的工具。有些甚至会让你控制这样的细节,如果你想要的话(例如 gnu ld 允许你提供一个脚本来告诉它如何对数据、代码等进行分组)

回答by Justicle

FYI, just backing up the other answers:

仅供参考,只是备份其他答案:

The standard: ISO/IEC 14882:2003says:

标准:ISO/IEC 14882:2003说:

2.13. String literals

  1. [...]An ordinary string literal has type “array of n const char” and static storage duration (3.7)

  2. Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementation- defined. The effect of attempting to modify a string literal is undefined.

2.13. 字符串文字

  1. [...]一个普通的字符串文字具有类型“数组n const char”和静态存储持续时间(3.7)

  2. 是否所有字符串文字都是不同的(即存储在非重叠对象中)是实现定义的。尝试修改字符串文字的效果是未定义的。

回答by Alex Budovski

gcc makes a .rodatasection that gets mapped "somewhere" in address space and is marked read only,

gcc 制作了一个.rodata在地址空间中被映射到“某处”并被标记为只读的部分,

Visual C++ (cl.exe) makes a .rdatasection for the same purpose.

Visual C++ ( cl.exe).rdata为相同目的创建一个部分。

You can look at the output from dumpbinor objdump(on Linux) to see the sections of your executable.

您可以查看dumpbinobjdump(在 Linux 上)的输出以查看可执行文件的各个部分。

E.g.

例如

>dumpbin vec1.exe
Microsoft (R) COFF/PE Dumper Version 8.00.50727.762
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file vec1.exe

File Type: EXECUTABLE IMAGE

  Summary

        4000 .data
        5000 .rdata  <-- here are strings and other read-only stuff.
       14000 .text

回答by Parappa

It depends on the formatof your executable. One way to think about it is that if you were assembly programming, you might put string literals in the data segment of your assembly program. Your C compiler does something like that, but it all depends on what system you're binary is being compiled for.

这取决于您的可执行文件格式。一种思考方式是,如果您在进行汇编编程,则可能会将字符串文字放入汇编程序的数据段中。你的 C 编译器会做类似的事情,但这完全取决于你的二进制文件是为什么系统编译的。

回答by Sahil Jain

String literals are frequently allocated to the read-only memory, making them immutable. However, in some compilers modification is possible by a "smart trick"..And the smart trick is by "using character pointer pointing to memory"..remember some compilers, may not allow this..Here is demo

字符串文字经常分配给只读内存,使它们不可变。但是,在某些编译器中,可以通过“智能技巧”进行修改......而智能技巧是“使用指向内存的字符指针”......记住一些编译器,可能不允许这样做......这里是演示

char *tabHeader = "Sound";
*tabHeader = 'L';
printf("%s\n",tabHeader); // Displays "Lound"

回答by mihai

As this might differ from compiler to compiler, the best way is to filter an object dump for the searched string literal:

由于这可能因编译器而异,因此最好的方法是过滤搜索字符串文字的对象转储:

objdump -s main.o | grep -B 1 str

where -sforces objdumpto display the full contents of all sections, main.ois the object file, -B 1forces grepto also print one line before the match (so that you can see the section name) and stris the string literal you're searching for.

其中-s强制objdump显示所有部分的完整内容,main.o是目标文件,-B 1强制grep在匹配之前打印一行(以便您可以看到部分名称),并且str是您正在搜索的字符串文字。

With gcc on a Windows machine, and one variable declared in mainlike

与海湾合作委员会在Windows机器上,和一个可变的声明main一样

char *c = "whatever";

running

跑步

objdump -s main.o | grep -B 1 whatever

returns

返回

Contents of section .rdata:
 0000 77686174 65766572 00000000           whatever....