我听说在C语言中,如果我执行以下代码:
char *s = "hello world".
“hello world”实际上存储在只读内存中。
我对只读内存不太清楚,什么是解释?这是否像一个标志,告诉编译器不要写入那个部分?
我听说在C语言中,如果我执行以下代码:
char *s = "hello world".
“hello world”实际上存储在只读内存中。
我对只读内存不太清楚,什么是解释?这是否像一个标志,告诉编译器不要写入那个部分?
可执行文件包含两部分:一个 .data 节段,包含全局变量;一个 .text 节段,包含实际的机器代码。
字符串被放置在 .data 节段内。当 C 语言看到 "Hello world" 时,它会将字符串 "Hello world" 放入可执行文件本身,并用该字符串加载到的地址替换程序中所有的 "Hello world" 实例。
话虽如此,我不确定为什么它是只读的 - 理论上,一个程序应该能够修改自己的内存。
真正的只读存储器由操作系统的存储器子系统实现。操作系统可以将某些页面标记为只读。
在二进制文件中,编译器可以告诉操作系统哪些可执行文件部分应该放在只读内存页上,哪些应该放在可读可写内存页上。
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
s[4] = '0';
并查看当您调用时是否显示“hello w0rld”
puts(s);
正如其他人所提到的,常量字符串的内容是否存储在只读内存中取决于操作系统、编译器和芯片架构。
更准确地说,C标准规定引用字符串被视为“const char []”类型(或类似的措辞,我手头没有标准)。
任何试图修改这种字符串内容的代码都会导致未定义行为。这意味着在那一点上可以发生任何事情,编译器的提供者甚至不需要记录可能发生的事情。
实际上,这意味着想要具有可移植性的C或C++程序必须避免修改常量字符串。
通常情况下,编译器不允许您修改“const”变量的内容,因此在大多数情况下可以将“const”视为“只读”。不幸的是,char *和const char *有一个特殊的例外,主要是出于历史原因。这意味着像这样的代码:
char *x = "Hello, World";
*x = 'h';
即使调用未定义的行为,也将无错误或警告编译。