2

任何人都知道为什么这个代码打印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;
}
4

2 回答 2

10

您正在从内部存储指向局部变量的指针initialize。在函数返回后,该内存地址不再有效,无法通过指针访问——您的程序在取消引用mainArea.root内部时调用未定义行为 (UB) main

根据定义,当调用 UB 时,任何事情都可能发生。你看到的是任何东西的某个版本。

出于实际编程目的,请在此处停止阅读。如果你很好奇为什么会出现这种行为,这里有一个解释:

在实践中发生的情况是,mainArea.root它指向堆栈上的一个“未使用”地址,就在main. 当您调用operator<<一个新的堆栈帧时,它会与 . 指向的内存重叠mainArea.rootoperator<<的(堆栈分配的)局部变量会覆盖该内存的内容,从main结果来看,这会导致看到修改后的值。

于 2013-08-17T10:19:06.520 回答
8

这个:

void initialize(){
    triangle root;
    mainArea.root = &root;
}

导致未定义的行为。

该变量triangle root;仅在函数执行期间持续存在。一旦函数返回,它就不再存在。因此mainArea.root,随机指向可以重新用于任何事情的内存。

mainArea.root因此,函数退出后的任何使用都是未定义的行为。这意味着应用程序可以做任何事情。

于 2013-08-17T10:19:43.793 回答