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

时间:2016-04-22 04:31:08

标签: c++ arrays function pointers return

我试图从我的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浮点四元数,所以我需要进行旋转,并且我在尝试编译时遇到了巨大的困难。现在它确实编译了,但我收到了这个警告。

有人可以向我解释为什么以及它意味着什么?

3 个答案:

答案 0 :(得分:8)

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::vectro<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;
}

答案 1 :(得分:1)

警告确切地说明了错误:您正在返回指向本地数组angles的指针。

局部变量并不重要,它们是简单的int变量,或类似你的数组,在函数返回时超出范围。这意味着它们会消失。有一个指向这个变量的指针意味着你不能再使用那个指针,因为它不再指向变量占用的内存。使用它将导致未定义的行为

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

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

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

答案 2 :(得分:1)

您需要将结果粘贴在堆上,以便它能够在返回本地函数后继续存在:

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

float * angles = new float[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;
}