c - 为什么声明到 main 函数中的局部字符串是 Rodata 段内存的一部分?

标签 c memory assembly reverse

反汇编后的代码如下:

#include <stdio.h>

static const char HELLO1[] = "Howdy";

int main(){
char hello2[6]="hello\0";
printf("%s",string);
}

我可以看到字符串 HELLO1 被声明到 .RODATA 段中,这是可以理解的,因为常量变量被声明到该段中。

但是,hello2 也被声明到 .RODATA 段中。但是局部变量是直接在Stack中声明的吧?

你能解释一下为什么这个字符串被声明到这个段中吗?

最佳答案

String literals在程序的生命周期内存在

String literals have static storage duration, and thus exist in memory for the life of the program.

Static storage duration .

The storage for the object is allocated when the program begins and deallocated when the program ends. Only one instance of the object exists. All objects declared at namespace scope (including global namespace) have this storage duration, plus those declared with static or extern.

于是gccELF二进制文件中.RODATA中实现了静态存储

进一步阐述...

char a[] = "Hello world A";
char* p  = "Hello world P";

对于ap,它们的字符串字面量都具有静态存储持续时间(这意味着它们都存储在.RODATA中),但有所不同因为对于 a,字符串文字被复制到这个堆栈变量中,而 p 只是指向 .RODATA 内存。这就是为什么你可以修改 a 但不能修改 p

注意:知道上面的引用来自 c++ 语法,但是 c 的原因是相同的

关于c - 为什么声明到 main 函数中的局部字符串是 Rodata 段内存的一部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39820406/

相关文章:

c - 如何扫描文本文件的字数和字数?

python - Python中的多处理内存错误

assembly - 摩托罗拉 6800 I 标志复位

objective-c - #include 或#import <objc/runtime.h>?

c - 如何将两个字节值合并为一个?

c++ - 从 32 位进程获取 64 位进程内存的入口点

assembly - 远跳到保护模式后的 GPF

从 bootloader 调用 32 位或 64 位程序

c - 在 C 中仅在父进程上 fork 多进程

linux - 内存压缩是如何实现的?