2016-04-22 50 views
0

我想從我的ODE(打開動態引擎)模擬體對象返回浮法X,Y和Z角度值。警告:局部變量「角度」的地址返回[-Wreturn-本地地址]

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個常量浮點四元,我需要再拿到旋轉和我已經試圖讓它來編譯巨大的困難。現在它編譯,但我得到這個警告。

任何人都可以向我解釋爲什麼,請問這意味着什麼?

+0

錯誤消息是相當清楚的。你將返回'angles'的地址,但是在你返回之後,'angles'不再存在。那麼調用者應該如何處理不再存在的對象的地址? –

+0

好吧,感謝清理東西:) – Jade

回答

3
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; 
} 
+0

'array '可能是適當的,因爲它似乎每次都返回相同的大小 –

+0

這很好,謝謝你的深入解釋。過去幾個月我一直只使用C++,但仍然對指針的工作方式感到困惑,因此非常感謝有用的建議。 – Jade

+0

@Jade,我很樂意提供幫助。快樂的編碼。 –

1

警告說,究竟出了什麼問題:你是返回一個指向本地陣列angles

局部變量,無所謂它們很簡單int變量或像你這樣的數組,在函數返回時超出範圍。這意味着它們會消失。指向這樣一個變量的指針意味着你不能再使用該指針,因爲它不再指向變量所佔用的內存。使用它將導致未定義的行爲

有兩個解決問題的方法:第一種方法是動態地分配使用new[]的陣列,並返回指針。分配到new[]的內存永遠不會超出範圍,直到您delete[]它。

第二個解決方案是定義在陣列主叫功能,和一個指針傳遞給它作爲參數,並有你的功能填寫英寸

由於我錯過,這是一個C++的問題,我寧願推薦第三種解決方案:使用std::array。然後,您可以在函數內部本地聲明數組,並返回該對象,並且該對象和編譯器將確保根據需要複製數據。

+0

這是一個C++的問題,所以malloc不應該真的被推薦 –

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; 
} 
相關問題