警告:返回局部变量"角度"的地址 [-Wreturn-local-addr]
warning: address of local variable 'angles' returned [-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 个常量浮点四元数,所以我需要然后获得旋转,并且我在尝试编译它时遇到了巨大的困难。现在它确实编译了,但我收到此警告。
谁能向我解释一下为什么以及这意味着什么?
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;
}
警告准确地说明了问题所在:您正在返回指向本地数组angles
的指针。
局部变量,不管它们是简单的int
变量,或者像你这样的数组,当它们的函数返回时,它们就会超出范围。这意味着它们有点消失了。拥有指向此类变量的指针意味着您不能再使用该指针,因为它不再指向变量占用的内存。使用它会导致未定义的行为。
您的问题有两种解决方案:第一种是使用 new[]
动态分配数组,并返回该指针。分配了new[]
的内存永远不会超出范围,直到您delete[]
它。
第二种解决方案是在调用函数中定义数组,并将指向它的指针作为参数传递,并让函数填充它。
由于我错过了这是一个C++问题,因此我宁愿推荐第三种解决方案: 使用std::array
.然后,您可以在函数中本地声明数组,并返回对象,对象和编译器将确保根据需要复制数据。
您需要将结果粘贴到堆上,以便它在本地函数的返回中幸存下来:
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;
}
- 将数组的地址分配给变量并删除
- 空基优化子对象的地址
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 如何在c++程序中找到函数的地址
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 被解释为低级别const的const对象的地址
- 将地址分配给本地指针后,公共对象的变量将消失
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 内联程序集printf将整数解释为地址
- 为什么指针不写入类的地址?
- 如何在C++中获取该对象的类声明中对象的地址?
- 通过按地址访问变量
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 函数名是c中该函数的第一条指令的地址吗
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- ReadProcessMemory() 不适用于像 0x2840C6C68D8 这样的长地址
- CUDA:统一内存和指针地址的更改
- 警告:返回局部变量"角度"的地址 [-Wreturn-local-addr]
- 如果我们在c++中使用static关键字删除[-Wreturn local-addr](警告:返回本地变量的地址),可以