push_back到指针列表会导致内存泄漏

时间:2011-10-05 12:34:14

标签: c++ visual-studio list memory-leaks

我正在尝试使用Visual Leak Detector查找内存泄漏。 它显示我m_neighbors.push_back(ent);导致泄漏。

(简短的callstack = NeighborCalculatorDummy - > foreach - > list - > allocate)

我将它用作NeighborCalculatorDummy<Entity *>,因此pushback应该只在列表中插入指针而不进行任何分配。 所有通过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;
});

3 个答案:

答案 0 :(得分:1)

在我看来,entity_type是一个指针(从for_each lambda判断)。

您可能想要使用

 NeighborCalculatorDummy<SomeEntity>

而不是

 NeighborCalculatorDummy<SomeEntity*>

在您的代码的其他位置(未显示)

当然,lambda拼写不同:

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

也许更多类似的点假定了entity_type的类型需要解除引用。

或者,您可以使用

  • vector<std::shared_ptr<entity_type> >而不是
  • 提升指针容器

当您的实体是多态类型或不可复制/可移动时,这些可能更合适。但是,更改代码可能还需要做更多的工作

答案 1 :(得分:0)

使用此定义,根据entity_type,代码将泄漏或不泄漏。

  • 如果entity_type是指针,则默认析构函数将只调用vector的析构函数。这将释放为这些指针分配的内存,但不会对它们调用delete。如果此类“拥有”向量中的项目并需要释放它们,则需要添加一个析构函数,该析构函数对向量中的所有项目调用delete。在这种情况下,您可能会考虑模板参数,并且不清楚这里是否需要指针。
  • 如果entity_type是值类型,则默认析构函数就足够了,因为向量中的副本将被向量的析构函数删除。

答案 2 :(得分:0)

我在Entity的父级中省略了虚拟析构函数。这就是为什么推迟它会导致泄密。

相关问题