在C语言中const类型的数据严格意义上可以修改:
const int a=1;
int*b=&a;
*b=2;
不同于C语言,C++中指针类型是要严格对应的,对const类型的数据必须使用const类型的指针进行接收,从而避免修改;
但问题是c++中同样支持指针的强制类型转换那么问题就出现了,对于下面这段代码输出就会显得不正常:
const int a=1;
int*b=(int*)&a;
*b=2;
cout<<a<<" "<<b<<endl;
cout<<&a<<" "<<b;
我们会发现对a和b,它们的值不同但是对应的地址不同,就好像出现了一个地址内包含两个值的情况。
回顾内存划分可以发现,const类型的数据一般存储在data区,而指针类型数据则通常存储在栈区,实际上不同的分区存储数据的规则不同,但一般不会出现相同的地址,除非以下两种情况:
- 内存映射:操作系统在虚拟内存中进行地址映射时,可能将不通过的存储区域映射到相同的虚拟地址。
- 编译器优化:编译器可能会对代码进行优化,将某些数据放在相邻的内存地址,包括不同存储区域的数据。这种优化可能导致栈上的变量和数据区的变量具有相同的地址。
如果说虚拟地址不是全局唯一的话就可以推测是对const强制类型转换后改变值的行为是未定义的,编译器进行了优化,在栈区重新开辟了一段地址用于进行修改,所以就出现了两个不同的变量拥有相同地址的情况。