【问题标题】:Return reference in c++ when use Visual Studio and Codeblocks使用 Visual Studio 和 Codeblocks 时在 C++ 中返回引用
【发布时间】:2018-05-24 19:15:49
【问题描述】:

我正在学习 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;
}

我知道这取决于编译器,但我想知道 在这种情况下哪个是正确的? 提前致谢!

【问题讨论】:

  • 您的代码调用了未定义的行为。您不能返回对局部变量的引用 - 这会导致引用悬空。
  • 感谢您的评论,我也希望我们更多地了解 VS2015 和 CodeBlocks 中的两个编译器。
  • 什么?!我从 VS2015 得到 "warning C4172: 返回本地变量或临时地址的地址:temp"。请在尝试运行代码之前检查online warning documentation。您只需单击错误列表中的数字即可到达!
  • 也许我已经关闭了 VS2015 中的所有警告。我将研究更多以再次打开它。谢谢。

标签: c++ visual-studio codeblocks


【解决方案1】:

首先请注意,决定程序行为的是编译器,而不是IDE(您用来编写代码的程序)。其他因素包括当前磁盘上的内容以及您作为输入获得的内容(例如来自用户、网络)、系统时钟等。

现在,正如@DeiDei 正确指出的那样,您会得到不同的行为,因为您的func() 函数返回对其本地变量的引用,并在其执行结束时超出范围。它在堆栈上的内存(或与之关联的寄存器)可能会被其他数据使用 - 您无法保证访问它时会发生什么。这是一个运行时具有Undefined Behavior 的可编译代码示例。

最后,大多数编译器都会警告您这一点 - 我确信您的 IDE 使用的两种编译器都是如此。所以你应该:

  1. 打开编译器警告标志。
  2. 阅读警告并解决它们。

【讨论】:

  • 感谢您的回答。通过这个小例子,我希望人们在使用任何编译器时更加小心
【解决方案2】:

您正在做的是未定义的行为,因为您正在返回对在函数超出范围时被破坏的东西的引用。在 VS2015 中有效的事实只是机会。

如果你想返回一个本地创建的对象,那么要么按值返回它,要么动态分配它并使用shared_ptrunique_ptr 将它作为指针返回。

【讨论】:

  • 感谢您的回答。通过这个小例子,我希望人们在使用任何编译器时更加小心
【解决方案3】:

真的很简单。当函数func 到达最后一行时,temp 的生命周期结束。每当您尝试访问该值时,都会出现segmentation fault,告诉您您正在尝试访问非法内存位置。

除了运气之外,我真的无法解释你在 Visual Studio 中取得成功的原因。

【讨论】:

  • 我认为 Visual Studio 编译器忽略了这个晦涩的点。
猜你喜欢
  • 2016-02-09
  • 2015-10-18
  • 1970-01-01
  • 2021-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多