警告:返回的局部变量“角度”的地址 \[-Wreturn-local-addr\]

新手上路,请多包涵

我正在尝试从我的 ODE(开放动态引擎)模拟中返回身体对象的浮点 x、y 和 z 角度值。

 float* Creature::eulerAngles(const float &q0, const float &q1, const float &q2, const float &q3){

    float angles[3] = {atan2(2 * (q0*q1 + q2*q3), 1 - 2 * (q1*q1 + q2*q2)),
                      asin( 2 * (q0*q2 - q3*q1)),
                      atan2(2 * (q0*q3 + q1*q2), 1 - 2 * (q2*q2 + q3*q3))};
    return angles;
}

因为 dBodyGetQuaternion 返回 4 个 const float 四元数,所以我需要然后得到旋转,我在尝试编译它时遇到了巨大的困难。现在它确实编译了,但我收到了这个警告。

谁能向我解释一下为什么以及这意味着什么?

原文由 Jade 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 403
2 个回答
float angles[3] = { ... };

定义一个本地数组。

该声明

return angles;

返回指向数组第一个元素的指针。

但是,一旦函数返回,数组就会被破坏。因此,返回的指针是一个悬空指针。

这就是编译器警告您的内容。如果在调用函数中取消引用返回的指针,则会调用未定义的行为。

为了返回指向在函数返回后仍然有效的数组的指针,您需要分配动态内存并返回动态内存。

 float* Creature::eulerAngles(const float &q0, const float &q1,
                             const float &q2, const float &q3)
{
   float* angles = new float[3];
   angles[0] = atan2(2 * (q0*q1 + q2*q3), 1 - 2 * (q1*q1 + q2*q2));
   angles[1] = asin( 2 * (q0*q2 - q3*q1));
   angles[2] = atan2(2 * (q0*q3 + q1*q2), 1 - 2 * (q2*q2 + q3*q3));

   return angles;
}

请记住,如果您执行上述操作,则必须确保在调用函数的返回指针上调用 delete []

为了避免手动分配和释放内存的麻烦,您可以使用 std::vector<float> 作为您的返回类型。

 std::vector<float> Creature::eulerAngles(const float &q0, const float &q1,
                                         const float &q2, const float &q3)
{
   std::vector<float> angles(3);
   angles[0] = atan2(2 * (q0*q1 + q2*q3), 1 - 2 * (q1*q1 + q2*q2));
   angles[1] = asin( 2 * (q0*q2 - q3*q1));
   angles[2] = atan2(2 * (q0*q3 + q1*q2), 1 - 2 * (q2*q2 + q3*q3));

   return angles;
}

这样,内存管理就会自动为您完成。

由于数组的大小固定为 3,因此使用 std::array<float, 3> 比使用 std::vector<float> 更好:

 std::array<float, 3> Creature::eulerAngles(const float &q0, const float &q1, const float &q2, const float &q3)
{
   std::array<float, 3> angles;
   angles[0] = atan2(2 * (q0*q1 + q2*q3), 1 - 2 * (q1*q1 + q2*q2));
   angles[1] = asin( 2 * (q0*q2 - q3*q1));
   angles[2] = atan2(2 * (q0*q3 + q1*q2), 1 - 2 * (q2*q2 + q3*q3));

   return angles;
}

原文由 R Sahu 发布,翻译遵循 CC BY-SA 4.0 许可协议

警告准确地说明了问题所在:您正在返回一个指向本地数组的指针 angles

局部变量,没关系,它们很简单 int 变量或像你这样的数组,当它们的函数返回时超出范围。这意味着它们会消失。拥有指向此类变量的指针意味着您不能再使用该指针,因为它不再指向该变量占用的内存。使用它会导致 _未定义的行为_。

您的问题有两种解决方案:第一种是使用 new[] 动态分配数组,然后返回该指针。分配给 new[] 的内存永远不会超出范围,直到您 delete[] 它。

第二种解决方案是在 调用 函数中定义数组,并将指向它的指针作为参数传递并让函数填充它。

由于我错过了这是一个 C++ 问题,因此我更推荐第三种解决方案:使用 std::array 。然后您可以在函数内本地声明数组,并返回对象和对象,编译器将确保根据需要复制数据。

原文由 Some programmer dude 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题