指针地址和引用混乱

时间:2019-02-19 00:25:17

标签: c++ pointers

我有两个几乎相同的代码段,它们应该产生相同的输出,除了它们不仅不同之外,我更改的一行以某种方式影响了无关的输出!

#include "stdafx.h"
#include <iostream>

using namespace std;

class Tag {
public:
    int num = 0;
    Tag* contains = nullptr;

    Tag::Tag(int n) { num = n; }

    void setContains(Tag t) { contains = &t; }

    int getNum() { return num; }
    Tag getContains() { return *contains; }
};

int main() {
    Tag tag1 = Tag(1); Tag tag2 = Tag(2);
    tag1.setContains(tag2);
    cout << tag1.getContains().getNum() << endl << (*tag1.contains).getNum() << endl;
    return 0;
}

此输出

8460735
8460735

或其他一些随机数。这告诉我我以某种方式输出了指针地址,而不是它所引用的对象。所以我改变了线

cout << tag1.getContains().getNum() << endl << (*tag1.contains).getNum() << endl;

cout << tag1.getContains().getNum() << endl << (*tag1.contains).num << endl;

然后我得到输出

2
2

等等,什么?如果第二行从地址更改为实际数字2,我知道了,但是为什么两者都更改为2?

2 个答案:

答案 0 :(得分:2)

res.header('Content-Type', 'application/json'); res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Headers', 'Content-Type'); if (req.method === 'OPTIONS') { res.status(204).send(''); } 使setContains指向局部变量。函数返回后,该变量将立即销毁,从而使contains悬空指针。任何使用它的尝试都会表现出不确定的行为。

实际上,contains从用于存放变量的堆栈中读取一些随机垃圾。对程序的轻微扰动会更改堆栈访问模式,从而在其中留下不同的垃圾。

答案 1 :(得分:1)

由于您要调用未定义的行为,因此将本地参数的地址保存到Tag* contains

void setContains(Tag t) { contains = &t; }

您应该直接通过引用或指针传递参数。否则,您只是将变量的地址保存在堆栈中,该地址在函数出口处销毁。

此后基于contains的一切都是未定义的行为。