2013-05-16 30 views
0

下面的代碼是從的DirectX教程取出並略作修改的新對象由我:這是否會導致內存泄漏?在分配函數調用

void Initialize() 
{ 
    // case 1 
    m_camera.SetLookAt(new D3DXVECTOR3(x_component, y_component, z_component )); 

    // case 2 
    m_camera.SetLookAt(&D3DXVECTOR3(x_component, y_component, z_component)); 

    // case 3 
    { 
    m_camera.SetLookAt(&D3DXVECTOR3(x_component, y_component, z_component)); 
    } 

    //more stuff to do here 
} 

void CCamera::SetLookAt(D3DXVECTOR3* pLookAt) 
{ 
    m_lookAt.x = pLookAt->x; 
    m_lookAt.y = pLookAt->y; 
    m_lookAt.z = pLookAt->z; 

    //delete pLookAt; // solution for case 1? 
} 

m_camera是類CCamera,其中有一個私有成員D3DXVECTOR3 m_lookAt的實例。 SetLookAt()函數接受一個指向D3DXVECTOR3的指針。

我的問題是,這個指針提供的方式(情況1和2)有什麼區別?

就我的理解而言,在情況1中,D3DXVECTOR是從堆中分配的。創建的指針傳遞給SetLookAt(),它複製數據並退出。然後,Initialize()退出,而不釋放D3DXVECTOR佔用的內存,導致內存泄漏。可能的解決方案是取消註釋SetLookAt()中的最後一行。

在情況2中,D3DXVECTOR被分配在堆棧上並且它的地址被傳遞給SetLookAt。這次,只有當Initialize()完成時,D3DXVECTOR纔會被釋放。

我的理解是否正確?如果我(在情況2中)想要在SetLookAt()函數結束後立即釋放D3DXVECTOR3佔用的內存?將SetLookAt()包裝在大括號中(情況3)是否足以強制創建的D3DXVECTOR3在SetLookAt完成後被釋放?

另外,如果調用SetLookAt()(在所有3種情況下),它會有什麼區別,向量將使用文字值調用,例如, D3DXVECTOR3(8.0f,0.0f,5.0f)而不是D3DXVECTOR3(x_component,y_component,z_component)?

+0

'案例1的解決方案?'不好的解決方案,函數不應該知道傳遞給它的指針是否必須被刪除。將這個'delete'移到調用者。 –

回答

2
在這種情況下

你應該使用const引用

void CCamera::SetLookAt(const D3DXVECTOR3& lookAt) 

案例2和案例3是相同
當你創建矢量有一個在它的工作原理沒有什麼區別:
D3DXVECTOR (D3DXVECTOR3(8.0f, 0.0f, 5.0f)D3DXVECTOR3(x_component, y_component, z_component)

0

在情況2和3(它們是相同的)中,你傳遞一個指向堆棧分配的匿名臨時指針。這很好,因爲堆棧不會退出,直到函數返回 ,以便指針保持有效。

匿名臨時會從堆棧中彈出一次.SetLookAt已完成,在2和3中這就是爲什麼冗餘。

第1種情況會泄漏,但您沒有刪除您當前已評論的內容。

+0

其實情況2和3是非法的,應該會導致編譯器錯誤。 – juanchopanza

+0

但在我看來,在msvc這個編譯併發出警告 – spiritwolfform

+0

是的,它確實在msvc上編譯,雖然gcc不會允許你傳遞一個匿名臨時引用。但這一切都是不好的做法。 – Bathsheba