任何机构都知道为什么此代码会打印a
而不是b
?
当我mainArea.root->rightBro
时,我测试了cout
值的变化。但为什么呢?
#include<iostream>
using namespace std;
struct triangle{
triangle *rightBro;
};
struct area{
triangle *root;
} mainArea;
void initialize(){
triangle root;
mainArea.root = &root;
}
int main()
{
initialize();
mainArea.root->rightBro = NULL ;
if (mainArea.root->rightBro == NULL) cout << "a" << endl;
if (mainArea.root->rightBro == NULL) cout << "b" << endl;
return 0;
}
答案 0 :(得分:10)
您正在initialize
内存储指向局部变量的指针。函数返回后,内存地址不再有效通过指针访问 - 当程序在mainArea.root
内取消引用main
时,程序会调用未定义的行为(UB)。
根据定义,当调用UB时,任何事情都可能发生。你看到的是任何版本的东西。
出于实际编程目的,请在此处阅读。如果你很好奇为什么要具体采取这种行为,这里有一个解释:
在实践中发生的事情是mainArea.root
在main
的堆栈帧之后指向堆栈上的“未使用”地址。当您调用operator<<
时,会分配一个新的堆栈帧,该堆栈帧与mainArea.root
指向的内存重叠。 operator<<
的(堆栈分配的)局部变量覆盖了该内存的内容,从main
的角度来看,这会导致看到修改后的值。
答案 1 :(得分:8)
此:
void initialize(){
triangle root;
mainArea.root = &root;
}
导致未定义的行为。
变量triangle root;
只有在执行函数时才会持续。函数返回后,它不再存在。因此,mainArea.root
指向可以重复用于任何事物的随机记忆。
因此,在函数退出后对mainArea.root
的任何使用都是未定义的行为。这意味着应用程序可以做任何事情。