2011-10-05 64 views
0

我想用Visual Leak Detector找到內存泄漏。 它顯示我m_neighbors.push_back(ent);導致泄漏。push_backing到指針列表導致內存泄漏

(簡要調用堆棧= NeighborCalculatorDummy - >的foreach - >列表 - >分配)

我使用它作爲NeighborCalculatorDummy<Entity *>,所以推回應該只在插入列表指針沒有任何分配。 所有通過addEntity來到實體的指針在代碼中的其他地方被刪除...

push_back怎麼可能導致泄漏?

template <typename entity_type> 
class NeighborCalculatorDummy 
{ 
public: 
    inline void addEntity(const entity_type & entity) 
    { 
     m_entities.push_back(entity); 
    } 

    void calculateNeighbors(const vector_type & position, flt32 radius) 
    { 
     flt32 rSq = radius*radius; 
     m_neighbors.clear(); 

     std::for_each(m_entities.begin(), m_entities.end(), [&](entity_type ent){ 
      if(lengthSq(ent->getPosition() - position) <= rSq) 
       m_neighbors.push_back(ent); 
     }); 
    } 

private: 
    std::vector<entity_type> m_entities; 
    std::list<entity_type> m_neighbors; 
}; 

編輯

這裏是圍繞NeighborCalculator

//#1 
std::list<Vehicle *> vehicles; 
vehicles.push_back(new Vehicle); 
vehicles.push_back(new Vehicle); 
vehicles.push_back(new Vehicle); 

//#2 
NeighborCalculatorDummy<Vehicle *> neighborCalculator = new NeighborCalculatorDummy<Vehicle *>(); 

std::for_each(vehicles.begin(), vehicles.end(), [&](Vehicle * vehicle){ 
    neighborCalculator->addEntity(vehicle); 
}); 

//#3 impl of addEntity 
template <typename entity_type> 
void NeighborCalculatorDummy<entity_type>::addEntity(const entity_type & entity) 
{ 
    ... 
    m_entities.push_back(entity); //m_entities is - std::vector<Vehicle *> 
} 

//#4 end of program 
delete neighborCalculator; 

std::for_each(vehicles.begin(), vehicles.end(), [&](Vehicle * vehicle){ 
    delete vehicle; 
}); 
+0

你在哪裏刪除動態分配內存的指針?你在哪裏分配它? –

+0

您可能需要添加更多信息,比如'entity_type'的類型以及如何使用NeighborCalculatorDummy(是否被銷燬?)如果泄漏的內存是在push_back調用中獲取的,那麼似乎表明該清單沒有被正確銷燬。 –

+0

CRT內存泄漏檢測儀是否顯示相同的泄漏? –

回答

0

我已經省略了Entity的父級虛擬析構函數。這就是爲什麼推回它導致泄漏。

1

代碼在我看來,這是entity_type指針(從拉姆達的for_each判斷)。

你可能想用

NeighborCalculatorDummy<SomeEntity> 

代替

NeighborCalculatorDummy<SomeEntity*> 

在其他地方你的代碼(未顯示)的

當然的拉姆達將被拼寫不同:

[&](const entity_type& ent){ 
     if(lengthSq(ent.getPosition() - position) <= rSq) 
      m_neighbors.push_back(ent); 
    } 

以及可能更類似的假設entity_type類型需要解除引用的點。

或者,你可以使用

  • vector<std::shared_ptr<entity_type> >代替
  • 升壓指針集裝箱

當你的實體是多態類型或非copyables /動產這些可能更合適。然而,它也可能有更多的工作來改變你的代碼

+0

儘管用戶可能希望使用不同的版本,但這並不能解釋內存泄漏。它不是「SomeEntity」對象,它不是被解除分配的對象,而是列表節點(這是從'push_back'內的'allocator'獲得的) –

+0

+1 std :: shared_ptr –

+0

我不想要像'NeighborCalcDummy '那樣使用它,因爲它會在'NeighborCalcDummy'中創建其他實體的列表。我只想用這個類的指針工作(因爲stl不允許創建vecotr /引用列表) – relaxxx

0

有了這個定義,取決於entity_type,代碼將會泄漏與否。

  • 如果entity_type是一個指針,默認的析構函數會調用vector的析構函數。這將釋放分配給這些指針的內存,但不會調用它們的刪除。如果此類「擁有」矢量內的項目並需要釋放它們,則需要添加一個析構函數,該矢量內的所有項目都將調用delete。在這種情況下,您可能會考慮模板參數,以及它沒有明確指出這裏需要指針。
  • 如果entity_type是一個值類型,那麼默認的析構函數就足夠了,因爲放置在向量中的副本將被向量的析構函數刪除。