我有两个几乎相同的代码段,它们应该产生相同的输出,除了它们不仅不同之外,我更改的一行以某种方式影响了无关的输出!
#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?
答案 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
的一切都是未定义的行为。