2013-04-09 54 views
0

我有一個程序,我有一個std ::向量作爲類的成員:C++的std ::向量::明確()崩潰

class Blackboard 
{ 
public: 
    inline std::vector<Vector2<int> > GetPath()   
    { return m_path; } 

    inline void SetPath(std::vector<Vector2<int> > path) 
    { m_path = path; } 

    inline void ClearPath()           
    { if(m_path.size() > 0) m_path.clear(); } 

private: 
    std::vector<Vector2<int>> m_path; 
}; 

凡Vector2類被定義爲:

template <class T> 
class Vector2 
{ 
private: 
    T m_x; 
    T m_y; 

public: 
    Vector2(void) 
    { m_x = 0; m_y = 0;} 

    Vector2(T x, T y)           
    { m_x = x; m_y = y;} 

    ~Vector2(void)          
    { } 

    inline T x() const         
    { return m_x; } 

    inline T y() const         
    { return m_y; } 

    // ... 
}; 

,在某些時候我打電話:

m_blackboard.ClearPath(); 

此工程在調試正常,但與「微軟的Visual Studio版本崩潰C運行時庫具有d在Test2.exe中檢測到一個致命錯誤。「信息。

調用堆棧,在最後的地步,我仍然可以看到表明:

Test2.exe!std::vector<RBT::Vector2<int>, 
std::allocator<RBT::Vector2<int> > >::erase 
(std::_Vector_const_iterator<RBT::Vector2<int>, 
std::allocator<RBT::Vector2<int> > > 
_First_arg={m_x=15 m_y=7 }, 
std::_Vector_const_iterator<RBT::Vector2<int>, 
std::allocator<RBT::Vector2<int> > > 
_Last_arg={m_x=15 m_y=8 }) Line 1037 + 0xe bytes C++ 

編輯: 這裏是我打電話給那個結束了崩潰的代碼:

BTNode::Status GoToDestBehavior::Update() 
{ 
    BTEntityData::Node* node = m_dataRef->m_bTree.GetNode(m_index); 
    if(node->m_state == BTNode::STATE_READY) 
    { 
     BehaviorTree::RequestDeferredAction(Batch::PATHFIND, m_dataRef->m_entityID); 
     return BTNode::STATE_RUNNING; 
    } 
    else if(node->m_state == BTNode::STATE_RUNNING) 
    { 
     std::vector<Vector2<int>> path = m_dataRef->m_blackboard.GetPath(); 

     EntitySystem::Entity* entity = EntitySystem::GetEntity(m_dataRef->m_entityID); 
     Assert(entity != NULL, "Invalid entity\n"); 

     Assert(entity->HasComponent(Component::PHYSICS_COMP), "Associated entity must have physics component to move\n"); 
     int phyIndex = entity->GetComponentIndex(Component::PHYSICS_COMP); 

     PhysicsSystem::PhysicsData * physicsData = PhysicsSystem::GetComponent(phyIndex); 
     Assert(physicsData != NULL, "Invalid physics data\n"); 

     // Path is empty, so finish 
     if(path.size() == 0) 
     { 
      physicsData->m_dir = Direction::NONE;  // Stop because we are here 
      return BTNode::STATE_SUCCESS; 
     } 

     // Remove last element if we are at it 
     //LogFmt("Size of vector %d\n", path.size()); 
     Vector2<int> last = path.back(); 
     if(last.x() == physicsData->m_posX && last.y() == physicsData->m_posY) 
     { 
      path.pop_back(); 
     } 

     // Last node of the path has been transversed 
     if(path.size() == 0) 
     { 
      physicsData->m_dir = Direction::NONE;  // Stop because we are here 
      m_dataRef->m_blackboard.ClearPath(); 
      return BTNode::STATE_SUCCESS; 
     } 

     Vector2<int> step = path.back();     

     physicsData->m_dir = Direction::VectorToDirection(physicsData->m_posX, physicsData->m_posY, step.x(), step.y()); 
     if(physicsData->m_dir == Direction::NONE) 
     { 
      m_dataRef->m_blackboard.SetPath(path); 
      return BTNode::STATE_FAIL; 
     } 
     m_dataRef->m_blackboard.SetPath(path); 
     return BTNode::STATE_RUNNING; 
    } 

    return BTNode::STATE_ERROR; 
} 

我不知道爲什麼它的行爲如此。我在網上發現的大多數類似問題都存在清空數組時調用清空的問題,但我有一個警惕,所以它不應該成爲問題。

我能想到的另一件事是我的Vector2類需要某種類型的拷貝構造函數,或者當我向vector中添加元素時,它最終只有2個整數,所以我不知道爲什麼會這樣失敗。

我一直在這個代碼太多,可能會漏掉一些明顯的東西。所有的幫助將不勝感激。

由於提前, 海梅

+7

在空載體上調用clear()是完全正確的,這個問題在別的地方,也就是說,在代碼執行之前,你的程序很可能有未定義的行爲 – 2013-04-09 20:04:35

回答

2

這是完全正常的調用clear任何形式的空容器上。

使用我的心理調試技巧,我確定在代碼中,您並未向我們展示您正在訪問實際上不存在的vector元素(可能在插入它們之前,可能還有operator[])。元素創建通常通過resize,push_backinsert完成。

另一種可能性是您的程序中有另一個內存損壞。

+0

編輯時顯示完整的調用崩潰,請看看。 – JaimeBarrachina 2013-04-09 20:22:14

+2

@JaimeBarrachina你必須擺脫這種想法:代碼崩潰的地方在某種程度上與錯誤所在的地方有關。它*可能*,但只有可能。對我來說,你的bug聽起來像堆腐敗,這可能發生在你的程序的任何部分。我會看看你的程序中正在分配新內存和/或正在操作指針的部分。 – john 2013-04-09 20:31:04

0

我發現了由於數據格式發生變化而導致的問題。我正在使用的std :: list從一個指針變爲一個列表直接到列表。這開始導致各種檢查列表大小的錯誤沒有解決,並且是由清除所有列表的跟蹤數據的ZeroMemory()/ memset()調用引起的,因爲它現在是類而不是指向列表的指針。

如果你有一個空列表,並且在崩潰時調用.clear(),那麼你很可能已經在Mark的回答中提到了內部跟蹤內存。尋找一個你正在做記憶清除的地方,把含有類和類似內容作爲最可能的罪魁禍首。