2012-03-21 61 views
1

我有一個類中的方法獲取指向另一個對象(不同類)的指針,並將一個對象(另一個不同的類)添加到作爲第一個對象(作爲參數傳遞的對象)的成員變量的向量。這是代碼:嘗試訪問指向矢量中某個對象的指針時發生無效訪問錯誤

ObstacleManager::ObstacleManager(Application *lApp) 
{ 
    app=lApp; 
    GLfloat obstacleVerts[12]={ 
    -0.1f,-0.2f,0.0f, 
    0.1f,-0.2f,0.0f, 
    -0.1f,0.2f,0.0f, 
    0.1f,0.2f,0.0f 
    }; 
    StandardObstacle obstacle(obstacleVerts,-0.7f,0.0f,4); 
    obstacle.manager=this; 
    lApp->characters.push_back(&obstacle); 
} 

我認爲問題是出障礙物對象被釋放時,它不應該,因爲如果我改變代碼,並用「新」(如果你創建了一個對象創建障礙新的,你必須手動刪除它,不是嗎?)它的工作原理。像這樣:

ObstacleManager::ObstacleManager(Application *lApp) 
{ 
    app=lApp; 
    GLfloat obstacleVerts[12]={ 
    -0.1f,-0.2f,0.0f, 
    0.1f,-0.2f,0.0f, 
    -0.1f,0.2f,0.0f, 
    0.1f,0.2f,0.0f 
    }; 
    StandardObstacle *obstacle=new StandardObstacle(obstacleVerts,-0.7f,0.0f,4); 
    obstacle->manager=this; 
    lApp->characters.push_back(obstacle); 
} 

有沒有辦法來防止這種情況發生?

+0

'lApp-> characters.push_back(obstacle);'+改變容器的T,但你真的應該學習指針,內存管理.. – 2012-03-21 19:42:19

+0

+更改容器是什麼意思? – XaitormanX 2012-03-21 19:54:37

回答

2

您正在將本地對象的地址傳遞給向量,一旦構造函數返回,本地對象就不存在,然後您的向量具有指向無效內存的指針。

你將不得不作出對象中存留,可能的方式是:
按值只需按下對象或
使用動態分配的對象,但不是原始指針使用智能指針像shared_ptr作爲向量元素類型。

+0

謝謝。我試圖有一個對象的向量而不是對象指針,但我無法設法讓它工作(這裏是一個問題有關的問題:[鏈接](http://stackoverflow.com/questions/9754354/only -the-last-object-of-a-vector-is-drawn-when-they-should-all-be-drawn/9776406#9776406))我不得不使用指針。我試圖使用智能指針 – XaitormanX 2012-03-21 19:57:04

+0

一個問題,如果我創建一個像這樣的智能指針: 'boost :: shared_ptr obstaclePtr(new StandardObstacle(obstacleVerts,-0.7f,0.0f,4));',請問它當它從任何地方不被引用時被刪除? – XaitormanX 2012-03-21 22:05:59

+0

@XaitormanX:是的。你必須小心,雖然你沒有任何循環引用。 – 2012-03-22 02:40:42

1

是的,你要麼創建對象new或使用智能指針。

你的直覺是正確的:

ObstacleManager::ObstacleManager(Application *lApp) 
{ 
    //... 
    StandardObstacle obstacle(obstacleVerts,-0.7f,0.0f,4); 
    obstacle.manager=this; 
    lApp->characters.push_back(&obstacle); 
} //obstacle is destroyed here 

對象obstacle被自動存儲創建。它的生命週期受其封閉範圍的限制,該範圍是構造函數中的右括號。

所以你把一個對象的地址,推入你的向量,然後對象被銷燬。這意味着,在向量中,你現在有一個懸掛指針。

這肯定會導致未定義的行爲

您可以像使用new一樣使用,並確保清理內存。或者你可以使用智能指針 - 這是更多的C + + - 比原始指針。