两个不同的值在相同的内存地址

#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,你已经承诺你不会修改它。 然后你去修改它。 这打破了编译器正在做的一个假设,结果,程序的行为不正确。

这被称为“未定义的行为” – 违反语言的假设之后,程序的行为是完全不确定的。 它不需要产生这样的输出 – 它可能已经产生了3342 ,或者坠毁,或者擦除了你的硬盘,或者通过你的鼻道召唤恶魔。 所以,不要修改常量值:)

 int * pN = const_cast<int*>(&N); *pN = 33; 

您的代码调用未定义行为1,因为您正在修改const限定variables/对象的内容。

1) 未定义的行为 :行为,例如在使用错误的程序结构或错误的数据时可能出现的,标准没有要求。[注意:允许的未定义行为的范围从忽略完全不可预知的结果,翻译或程序以环境特征(有或没有发布诊断信息)的方式执行,终止翻译或执行(通过发布诊断信息)。

const_cast在你的代码中,只要把一个指针'Pn'移交给'N','N'可以被修改。 “N”的地址与切换指针“Pn”的地址相同