Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 指针地址和引用混淆_C++_Pointers - Fatal编程技术网

C++ 指针地址和引用混淆

C++ 指针地址和引用混淆,c++,pointers,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

我有两段几乎相同的代码,它们应该会产生相同的输出,除了它们不同之外,我更改的那一行不知何故影响了不相关的输出

#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;
}
或者其他一些随机数。这告诉我我是在输出指针地址,而不是它所引用的对象。所以我改变了路线

cout << tag1.getContains().getNum() << endl << (*tag1.contains).getNum() << endl;
等等,什么?如果第二行从地址变为实际的数字2,我就知道了,但是为什么两者都变为2呢?

setContains指向一个局部变量。一旦函数返回,变量就会被销毁,留下一个悬空指针。任何使用它的尝试都会显示未定义的行为


实际上,contains->num从变量所在的堆栈中读取一些随机垃圾。对程序的轻微干扰会改变堆栈访问模式,从而在其中留下不同的垃圾。

因为您正在调用未定义的行为,所以您将本地参数的地址保存到标记*包含在此处:

您应该通过引用或指针直接传递参数。否则,您只需在堆栈上保存一个变量的地址,该变量在函数退出时被销毁


基于包含的所有内容都是未定义的行为。

我明白了。所以我应该在setContains的参数中使用指向标记地址的指针,而不是标记本身?如果您可以进一步详细说明,为什么我的*tag1.contains.num行输出不奇怪,而不是像它那样的数字2?由于tag1.contains是一个悬空指针,因此当tag1.getContains没有解析时,*tag1.contains如何解析为实际标记?函数调用越少,对堆栈的写入就越少。2曾经所在的内存位置在一种情况下恰好没有被覆盖,而在另一种情况下被其他内容覆盖。明白了,有道理。谢谢尝试激活警告。
cout << tag1.getContains().getNum() << endl << (*tag1.contains).getNum() << endl;
cout << tag1.getContains().getNum() << endl << (*tag1.contains).num << endl;
2
2
void setContains(Tag t) { contains = &t; }