Push_backing 进入指针列表会导致内存泄漏

发布于 2024-12-08 16:27:33 字数 1926 浏览 1 评论 0 原文

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

(brief callstack = NeighborCalculatorDummy -> foreach -> list -> allocate)

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

I am trying to find memory leak with Visual Leak Detector.
It shows me m_neighbors.push_back(ent); causes leak.

(brief callstack = NeighborCalculatorDummy -> foreach -> list -> allocate)

I use it as NeighborCalculatorDummy<Entity *>, so pushback should just insert pointer in list without any allocation.
All pointers to entities which come through addEntity are deleted elsewhere in code...

How is it possible for push_back to cause a leak?

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;
};

edit

here is the code around 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;
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

2024-12-15 16:27:33

在我看来,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);
    }

并且可能有更多类似的地方假设实体类型需要取消引用。

或者,您可以使用

  • vector; > 而不是
  • Boost Pointer Containers

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

It seems to me that entity_type is a pointer (judging from the for_each lambda).

You probably wanted to use

 NeighborCalculatorDummy<SomeEntity>

instead of

 NeighborCalculatorDummy<SomeEntity*>

in some other place of your code (not shown)

Of course the lambda would then be spelled differently:

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

and perhaps more similar spots that assumed the type of entity_type needed dereferencing.

Alternatively, you could use

  • vector<std::shared_ptr<entity_type> > instead
  • Boost Pointer Containers

These might be more appropriate when your entities are polymorphic types or non-copyables/movables. However, it is also likely more work to change you code around

Bonjour°[大白 2024-12-15 16:27:33

通过这个定义,根据entity_type,代码是否会泄漏。

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

With this definition, depending on entity_type, the code will leak or not.

  • If entity_type is a pointer, the default destructor will just call the destructor of vector. This will free the memory allocated for these pointers, but it will not call delete on them. If this class "owns" the items inside the vector and needs to free them, you need to add a destructor that calls delete for all items inside the vector. In this case, you might think about the template parameter as well as it does not make clear that a pointer is needed here.
  • If entity_type is a value type, the default destructor is sufficient as the copies placed into the vector will be deleted by the destructor of the vector.
高速公鹿 2024-12-15 16:27:33

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

I have omitted virtual destructor in Entity's parent. That is why pushbacking it caused a leak.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文