指针地址和参考混乱
Pointer address and reference confusion
我有两个几乎相同的代码,它们应该产生相同的输出,除了它们不仅不同,我更改的一行以某种方式影响了无关的输出!
#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;
to
cout << tag1.getContains().getNum() << endl << (*tag1.contains).num << endl;
我得到输出
2
2
等等,什么?如果第二行从地址更改为实际数字2,我会得到它,但是为什么两者都会更改为2?
setContains
使 contains
指向局部变量。函数返回后,该变量将立即销毁,而contains
是悬空的指针。任何尝试使用它的尝试都表现出不确定的行为。
实际上,contains->num
从堆叠的堆栈中读取一些随机垃圾,其中变量曾经播放。对程序的轻微扰动会改变堆栈访问模式,在那里留下不同的垃圾。
,因为您调用了未定义的行为,所以您将本地参数的地址保存到Tag* contains
:
void setContains(Tag t) { contains = &t; }
您应该直接通过参考或指针传递参数。否则,您只是保存在功能退出时被破坏的堆栈上的变量的地址。
之后基于contains
的所有内容都是不确定的行为。
相关文章:
- C++错误消息*成员参考.**初学者*
- 如何克服提升精神AST混乱
- 在决定是通过参考还是通过价值时,尺寸真的是一个问题吗
- 参考资源文件VC++中的$(SolutionDir)
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 为什么在运算符重载时需要参考?
- 使 \page 和 \subpage 参考 doxygen 中的方法文档
- std::shared_ptr 自定义参考计数器
- 英特尔 TBB 程序不会终止,可能会误用参考计数器
- 避免在基于反向范围的for循环实现中悬挂参考
- 通用参考 l 值不复制对象
- 标准::enable_if和通用参考的使用差异
- 标准::积累参考?
- C++丢失了参考
- 我可以有一个 ELI5 作为参考和指针以及何时使用它们吗?
- 矢量的通用参考
- 为什么"fun(i)"被推导出为"fun<int&>"而不是"fun<int>",因为"i"是"int"的类型而不是参考?
- C++17 和静态临时生存期的参考扩展
- C++ 参考:这两个语句有什么区别?
- 指针地址和参考混乱