我在C听说过,如果我这样做的话
char *s = "hello world".
Run Code Online (Sandbox Code Playgroud)
"hello world"实际上存储在只读存储器中.
我不太清楚只读内存.解释是什么?这是否像编译器的标志,告诉编译器不写入该部分?
Nil*_*nck 32
这不是C语言的一个特性,而是编译器/链接器和操作系统协同工作的一个特性.
编译此类代码时,会发生以下情况:
编译器会将字符串放入只读数据部分.
链接器收集此类只读部分中的所有数据,并将它们放入单个段中.该段驻留在可执行文件中,并标记为"只读"属性.
现在是操作系统可执行加载器.它加载可执行文件(或将其映射到内存中更精确).完成此操作后,加载程序将遍历各个部分并为每个段设置访问权限.对于只读数据段,它很可能会禁用代码执行和写访问.代码(例如,您的函数)获取执行权限但没有写访问权限.像静态变量这样的普通数据会获得读写访问等等......
这就是现代操作系统的功能.
如上所述,它不是C语言的一个特性.例如,如果为DOS编译相同的问题,程序将运行但不能进行写保护,因为DOS加载程序不知道只读部分.
真正的只读内存是由操作系统的内存子系统实现的。操作系统可以将某些页面标记为只读。
在二进制文件中,编译器可以告诉操作系统可执行文件的哪些部分应放置在只读内存页和读写内存页中。
可执行文件包含两部分:.data部分,包含全局变量; .text部分,包含实际的机器代码.
字符串放在.data部分中.当C语言看到"Hello world"时,它会将字符串"Hello world"放入可执行文件本身,并将程序中"Hello world"的实例替换为该字符串最终加载的地址.
话虽如此,我不确定为什么它是只读的 - 理论上程序应该能够修改自己的内存..
小智 5
当你写char s[10]="sneha";您在目标文件中分配了 10 个字节的存储空间(不是内存,只有在执行程序时内存才会出现)。这是内存的静态分配(在编译时)。
但是当您写入时,char *s="sneha";您没有分配任何存储空间来存储"sneha". 它将存储在只读部分。但是指针s根据声明的位置存储在不同的部分中。但它指向只读数据"sneha"。因此,如果您尝试在其上写入,则会出现分段错误。
例如:
char *s = "sneha";
s[1] = 'N';
printf("%s",s); // you expecting output sNeha,
// but you get a seg fault since it is READ ONLY DATA
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13097 次 |
| 最近记录: |