【问题标题】:C++: Looking for correction for "returning address of local variable..." [duplicate]C ++:寻找“局部变量的返回地址......”的更正[重复]
【发布时间】:2020-06-13 15:05:29
【问题描述】:

我目前正在参加一个在线 C++ 课程来填补我失业期间的时间,并且我有一个关于返回局部变量地址的问题。我意识到这不是推荐的做法,我正在寻找我正在尝试做的事情的替代解决方案(返回数据以复制到我的对象“co”,这是一个类 Coord 对象)。顺便说一句……该程序就结果而言是有效的。但它确实收到警告 C4172“返回局部变量或临时地址的地址......”。你能帮帮我吗?

这里是细节:在我的作业程序中,我有一个函数返回局部变量 Coord co 的地址(Coord 是我构造的具有两个 int 字段的类......显然......坐标)。我的目标是使用 Coord 复制构造函数通过该局部变量的地址复制数据。

//调用程序声明类Coord的对象co如下

Coord co;

//调用程序可以在几个地方调用函数requestMove()。 //这里是调用之一

co = bd.requestMove(pHuman);

//requestMove()的签名是

const Coord& requestMove(Player&);

//被调用函数requestMove()有一个本地坐标对象nodeAddress,它填充nodeAddress。返回语句为:

return nodeAddress;

欢迎提出意见和建议。非常感谢。

【问题讨论】:

  • 根本不允许返回对局部变量的引用。为什么不通过复制返回Coord?所以签名是Coord requestMove(Player&);
  • 按值返回,RVO 将使其与按引用返回一样高效
  • 我只是在学习如何使用 Stack Overflow ...所以我将在这里输入并让您知道我正在接受所有内容(您的所有答案)并将到达今天晚些时候致力于解决方案/更新。谢谢,这么快就回复了。

标签: c++


【解决方案1】:

该对象将在范围退出后被销毁,因此它的内存未分配,并且有一个指向该内存的对象意味着它是未定义的行为。最佳解决方案是将返回语句更改为return Coord{args...};,并将函数签名更改为Coord requestMove(Player&);,它将利用保证copy ellision,这意味着auto co = bd.requestMove(pHuman);将导致auto co = Coord{args...};

【讨论】:

  • 感谢您如此迅速地回复。我会在今天晚些时候研究您的建议(以及所有其他建议),并在我的更新中返回 Stack Overflow。再次感谢。
【解决方案2】:

您可以返回对临时持续时间对象的引用,但这只是将自己射入脚底的方法之一。 C++ 不是保姆语言,它允许这样做。

考虑:

foo& bar() {
    foo f;
    return f;
}

这段代码会编译,但是会发生什么?一开始你创建了一个对象f,但是当你从bar返回时,对象f超出了作用域并被破坏(这是RAII的本质)。返回的引用将是对不再存在的对象的“狂野引用”,并且尝试访问该内存位置只是未定义的行为(这是一种很好的方式来说明程序将做什么 - 没人知道。对于所有人它可以崩溃的意图和目的,它可以吃掉你的猫或给你煮咖啡)。

编译器只是警告您代码可能不会按照您的预期执行。

更正的是在这里按值返回对象。

foo bar() {
    foo f;
    return f;
}

【讨论】:

  • 感谢您这么快回复我并详细回复。稍后我将对此进行研究,并将返回此处更新所有内容。再次感谢。
猜你喜欢
  • 2021-04-28
  • 2013-01-30
  • 2012-09-07
  • 1970-01-01
  • 2011-04-13
  • 2023-03-11
  • 2011-10-17
  • 1970-01-01
相关资源
最近更新 更多