我还是c ++的新手并且一直在研究对象范围 我测试了下面的代码并目睹了一些奇怪的行为。
struct Test
{
int value, value2;
Test() : value(1), value2(10) {};
};
Test* GetTestPointer() {
Test t;
t.value = 20;
return &t;
}
int main() {
Test* tp = GetTestPointer();
int a = tp->value;
int b = tp->value2;
cout << a << endl;
cout << b << endl;
return 0;
}
输出:
20
10
我认为Test t
会超出范围,因此在main中取消引用其值会抛出异常或空值。为什么它会像对象还活着一样获得有效值?
实际上这就是我最初的尝试:
Test* tp = GetTestPointer();
cout << tp->value << endl;
cout << tp->value2 << endl;
输出:
20
18223279
此处value2
的行为无效,但我可以value
就好了。
相反,我尝试重新排序:
Test* tp = GetTestPointer();
cout << tp->value2 << endl;
cout << tp->value << endl;
输出:
10
1459403656
请注意,当我按预期正确启动tp
new
时,没有发生这种情况。
我知道在现实生活中我永远不会写这样的代码,但我真的很好奇为什么会发生这种情况。
t
何时超出范围?cout
的排序与tp
取消引用的内容有什么关系? 答案 0 :(得分:2)
你很幸运能够获得正确的价值,但一般情况下它是未定义的行为,你的编译器应警告你。
尝试将您的示例扩展为以下内容:
new
您将看到不同的输出,因为您的本地范围delete
对象被另一个函数调用覆盖。
当您使用{{1}}语句时,您的对象不是在本地创建的,而是在HEAP内存上创建,因此当您退出函数范围时它是有效的。在这种情况下,您必须使用{{1}},以便稍后删除此对象。