使用指针写入常量变量会导致运行时错误。系统如何知道被访问的地址是否为常量
const int i;
int *p;
void main()
{
p = (int*)&i;
*p = 10; // Causes runtime error
}
但在Windows系统中,一切都从RAM本身运行。
当我打印const变量和正常变量的地址时,我可以看到它们处于不同的偏移量。
系统如何知道指针访问的地址是const
?
使用指针写入常量变量会导致运行时错误。系统如何知道被访问的地址是否为常量
const int i;
int *p;
void main()
{
p = (int*)&i;
*p = 10; // Causes runtime error
}
但在Windows系统中,一切都从RAM本身运行。
当我打印const变量和正常变量的地址时,我可以看到它们处于不同的偏移量。
系统如何知道指针访问的地址是const
?
严格来说,根据C语言标准,您的代码会产生未定义的行为。
实际上,链接器可能已将变量i
放置在可执行映像的RO部分中。
因此写操作*p = 10
导致内存访问冲突(又名分段错误)。
RO =只读... –
RO部分是否驻留在RAM本身中? –
@AllEldhose:我在这里的评论的其余部分不是由C语言标准决定的,但基本上取决于底层平台(操作系统,虚拟内存,编译器,链接器等)。通常,整个可执行映像被加载到RAM中。有时它的一部分可能会被“换出”到硬盘中,以便为其他应用程序“腾出空间”。但基本上,当它运行时 - 它是从RAM运行的(再次,取决于你的平台 - 例如,有硬件架构可以运行所有的Flash)。 –
系统如何知道....
理想情况下,系统不需要知道。对于具有const
限定类型的对象,分配(一般情况下)将处于只读部分,因此任何尝试修改(写入)都将导致访问冲突。这是应该知道的程序员。
当我印刷
const
变量和正常变量的地址,我可以看到,他们在不同的偏移。
是的,这是有可能的,因为正常变量驻留在读写内存,而const
变量将驻留在只读存储器中。
请注意,有没有语法(或编译)错误为您的代码段。只有代码(运行时)的行为未定义。
仅供参考,引用C11
,章§6.7.3/ P6
如果试图通过与非常量限定左值的使用 修改与常量限定类型定义的对象类型,行为是未定义的。 [...]
链接器已将全局变量'i'放置在可执行映像的RO部分中。 –
* p = 10个未定义的行为。 – 2016-08-24 06:01:29