2016-08-24 32 views
3

使用指针写入常量变量会导致运行时错误。系统如何知道被访问的地址是否为常量

const int i; 
int *p; 
void main() 
{ 
    p = (int*)&i; 
    *p = 10;   // Causes runtime error 
} 

但在Windows系统中,一切都从RAM本身运行。

当我打印const变量和正常变量的地址时,我可以看到它们处于不同的偏移量。

系统如何知道指针访问的地址是const

+5

链接器已将全局变量'i'放置在可执行映像的RO部分中。 –

+1

* p = 10个未定义的行为。 – 2016-08-24 06:01:29

回答

5

严格来说,根据C语言标准,您的代码会产生未定义的行为。

实际上,链接器可能已将变量i放置在可执行映像的RO部分中。

因此写操作*p = 10导致内存访问冲突(又名分段错误)。

+0

RO =只读... –

+0

RO部分是否驻留在RAM本身中? –

+0

@AllEldhose:我在这里的评论的其余部分不是由C语言标准决定的,但基本上取决于底层平台(操作系统,虚拟内存,编译器,链接器等)。通常,整个可执行映像被加载到RAM中。有时它的一部分可能会被“换出”到硬盘中,以便为其他应用程序“腾出空间”。但基本上,当它运行时 - 它是从RAM运行的(再次,取决于你的平台 - 例如,有硬件架构可以运行所有的Flash)。 –

4

系统如何知道....

理想情况下,系统不需要知道。对于具有const限定类型的对象,分配(一般情况下)将处于只读部分,因此任何尝试修改(写入)都将导致访问冲突。这是应该知道的程序员。

当我印刷const变量和正常变量的地址,我可以看到,他们在不同的偏移。

是的,这是有可能的,因为正常变量驻留在读写内存,而const变量将驻留在只读存储器中。

请注意,有没有语法(或编译)错误为您的代码段。只有代码(运行时)的行为未定义。

仅供参考,引用C11,章§6.7.3/ P6

如果试图通过与非常量限定左值的使用 修改与常量限定类型定义的对象类型,行为是未定义的。 [...]

相关问题