C++;指针输出一致性 我试图学习C++中的指针。我正在运行下面的代码,以查看不同指针中的地址和值 #include <iostream> using namespace std; int main() { int x=10; int *p = &x; char c2 = 'c'; char *p2 = &c2; //cast to void pointer to see address in p2 void *p3 = static_cast<void *>(p2); cout<<"Address in p2/p3:"<< p3 <<endl; cout<<"Content of address in p2/p3:"<< *(static_cast<int *>(p3))<<endl; }

C++;指针输出一致性 我试图学习C++中的指针。我正在运行下面的代码,以查看不同指针中的地址和值 #include <iostream> using namespace std; int main() { int x=10; int *p = &x; char c2 = 'c'; char *p2 = &c2; //cast to void pointer to see address in p2 void *p3 = static_cast<void *>(p2); cout<<"Address in p2/p3:"<< p3 <<endl; cout<<"Content of address in p2/p3:"<< *(static_cast<int *>(p3))<<endl; },c++,c++11,C++,C++11,然后,它开始在我每次运行时打印垃圾值。但指针p3现在与x和p无关。有人能解释一下这里发生了什么事吗 提前感谢。您违反了严格的别名规则。由于p3最终指向的是char,因此您无法将静态转换为int*,并获得可靠的结果。如果将static\u cast转换为char*(实际类型p3指向): cout内存布局是这样的:10(小端)后面紧跟着“c”(ASCII 99)和10*256+99=2659 在许多情况下,UB是相当可预测的行为。未定义的行为。当p和x存在时,输出是否一致?是的,有一个原因:这就是它

然后,它开始在我每次运行时打印垃圾值。但指针p3现在与x和p无关。有人能解释一下这里发生了什么事吗


提前感谢。

您违反了严格的别名规则。由于
p3
最终指向的是
char
,因此您无法将
静态转换为
int*
,并获得可靠的结果。如果将
static\u cast
转换为
char*
(实际类型
p3
指向):


cout内存布局是这样的:10(小端)后面紧跟着“c”(ASCII 99)和10*256+99=2659


在许多情况下,UB是相当可预测的行为。

未定义的行为。当p和x存在时,输出是否一致?是的,有一个原因:这就是它与特定编译器和操作系统的工作方式。自动作用域中的对象原来是堆栈上的特定布局,因此,指针最终指向一致的内存内容。请注意,2659是十六进制的
0x00000a63
。指针最后部分看到了
x
变量中的
0x0a
字节。
0x63
部分是小写
c
的ASCII码。我知道我做的事情不对。基本上,我在学习指针。我不明白为什么在上面某个地方定义了int变量时,输出是一致的。我已经提到,我期望的是垃圾值。我的问题是为什么它不是junkt这是一个典型的未定义行为的非解释。它是一致的输出,因为程序恰好以这种方式布置内存。假设一个4字节的
int
,您将把3个字节读入
c2
之后的任何内容;在你的例子中,它恰好是
x
,但这不能保证。实际上,编译器的选项很少。在声明变量时,通过增加地址顺序分配变量是一种非常自然/不可避免的方式。在big endian机器上的价值可能是垃圾。我理解你的观点。如果你有时间的话,你能解释一下计算结果吗?10*256+99=2659。@Fayaz:任何袖珍计算器都会确认的。这与计算结果无关。我不明白的是为什么我们把10乘以256再加上99。我知道10是变量的值,99是c的ascii值。你们怎么把它们放在一起的,我不明白。@Fayaz,因为它们是在同一个片段中放在一起的。。当您读取那个地址时,您已经读取了包含这两个变量的更大的存储器,得到的值是它们的二进制表示形式对于LITTLE_ENDIAN CPU的值。这取决于编译器和CPU体系结构是否会发生这种情况。一般来说,这是UB,您也可能导致SEG故障
int x=10;
int *p = &x; 
    cout<<"Content of address in p2/p3:"<< *(static_cast<char *>(p3))<<endl;