我正在学习C ++。我使用visual studio 2015和codeblocks IDE来编写C ++代码。我尝试编写一个程序,从函数返回一个引用变量,我从2 IDE(Visual Studio 2015和代码块)得到不同的结果(两个结果),虽然我运行相同的代码。我尝试编写以下代码:
#include <iostream>
using namespace std;
class Demo
{
public:
int a;
};
//I wrote a function that returns a reference variable
Demo& func()
{
Demo temp;
temp.a = 1;
return temp;
}
int main()
{
Demo& d = func(); //it error if I run this code on Codeblocks and it run
//smoothly if I run it on Visual Studio 2015
cout<<d.a;
return 0;
}
我知道这取决于编译器,但我想知道 在这种情况下哪个是正确的? 提前谢谢!
答案 0 :(得分:2)
首先请注意,决定程序行为的是编译器而不是IDE(用于编写代码的程序)。其他因素是当前在磁盘上的内容以及您作为输入获得的内容(例如来自用户,网络),系统时钟等。
现在,正如@DeiDei正确指出的那样,您会得到不同的行为,因为您的func()
函数返回对其本地变量的引用,并在执行结束时超出范围。它在堆栈上的内存(或与之关联的寄存器)可能会被其他数据使用 - 并且您无法保证访问它时会发生什么。这是可编译代码的示例,其在运行时具有Undefined Behavior。
最后,大多数编译器都会对此发出警告 - 我确信这对于IDE使用的两个编译器都是如此。所以你应该:
答案 1 :(得分:1)
您正在做的是未定义的行为,因为您返回对函数超出范围时销毁的内容的引用。在VS2015中有效的事实只是机会。
如果要返回本地创建的对象,则按值返回,或者动态分配它,并使用shared_ptr
或unique_ptr
将其作为指针返回。
答案 2 :(得分:1)
这很简单。当函数func
到达最后一行时,temp
的生命周期就会消失。每当您尝试访问该值时,都会出现segmentation fault
,告诉您正在尝试访问非法内存位置。
我真的不能解释你在Visual Studio中取得成功的原因而不是运气。