两个不同的值在相同的内存地址
码
#include <iostream> using namespace std; int main() { const int N = 22; int * pN = const_cast<int*>(&N); *pN = 33; cout << N << '\t' << &N << endl; cout << *pN << '\t' << pN << endl; }
产量
22 0x22ff74
33 0x22ff74
为什么在同一地址有两个不同的值?
为什么在同一地址有两个不同的数据?
没有。 编译器可以优化任何提到的const,就好像你在那里编写了它的编译时间值。
请注意,编译器也被允许生成代码,在运行时删除硬盘,如果执行一些令人讨厌的技巧,比如写入内存保留为const。
你在行上得到未定义的行为*pN = 33;
,因为你正在修改一个const值。 任何事情都可能发生。 不要这样做。
可能,但是,你的编译器只是优化。 在该行中:
cout << N << '\t' << &N << endl;
它知道N
是一个常数expression式,值为22,所以只是将行更改为:
cout << 22 << '\t' << &N << endl;
在你的下一行,你把地址N
处的值提到“你设置”为33.(但实际上,你所做的只是删除了有关你的程序状态的任何保证)。
通过说明N
是const,你已经承诺你不会修改它。 然后你去修改它。 这打破了编译器正在做的一个假设,结果,程序的行为不正确。
这被称为“未定义的行为” – 违反语言的假设之后,程序的行为是完全不确定的。 它不需要产生这样的输出 – 它可能已经产生了33
或42
,或者坠毁,或者擦除了你的硬盘,或者通过你的鼻道召唤恶魔。 所以,不要修改常量值:)
int * pN = const_cast<int*>(&N); *pN = 33;
您的代码调用未定义行为1,因为您正在修改const
限定variables/对象的内容。
1) 未定义的行为 :行为,例如在使用错误的程序结构或错误的数据时可能出现的,标准没有要求。[注意:允许的未定义行为的范围从忽略完全不可预知的结果,翻译或程序以环境特征(有或没有发布诊断信息)的方式执行,终止翻译或执行(通过发布诊断信息)。
const_cast在你的代码中,只要把一个指针'Pn'移交给'N','N'可以被修改。 “N”的地址与切换指针“Pn”的地址相同