内存释放冻结了我的程序

时间:2013-05-09 15:00:54

标签: c++ pointers memory-management

这不是问题,只是我想回答的问题。

我正在制作有粒子的2D应用程序。在点击处理程序中,我编写了这段代码:

Particle *tempp = new Particle();
tempp->setPosition(mx, my);
particles.push_back(tempp); // typeof particles = std::list<Particle*>
delete tempp; // <- this line is the problem

单击时,将在鼠标位置创建一个粒子。大约一秒后,它应该消失,这很好。它消失后我可以再次点击以创建一个新的粒子。

但是,当我点击屏幕上仍然有一个粒子时,我的程序冻结并停止工作。

Particle类的析构函数和它的父析构函数都是空的。

没有调用delete我的程序运行正常,即使一次有多个粒子,甚至每帧多个。我只是想知道造成这种冻结问题的原因。

5 个答案:

答案 0 :(得分:4)

根据发布的代码,particles容器将包含悬空指针。任何取消引用这些的尝试都是未定义的行为。我假设它们后来被使用,否则它们的存储似乎毫无意义。

调用push_back()不会复制指向对象,而是复制指针的值(动态分配的对象的内存地址)。如果Particle复制成本低,则可复制且多态行为是不需要的,只需将Particle存储在容器中即可。否则,建议使用智能指针(例如std::unique_ptr)在从容器中删除时自动销毁Particle

答案 1 :(得分:3)

当您将指针推入列表时,您只需按下实际指针的副本,而不会复制其指向的内容。这意味着在push_back之后你有两个指针指向相同的内存。

如果你随后释放了那个内存,那么你有一个指向空闲内存的指针,而且该指针现在无效。

答案 2 :(得分:3)

当我看到new然后几行delete时,我宁愿看到使用的堆栈。除非Particle是巨大的(我怀疑),否则您可以将代码更改为:

Particle tempp;
tempp.setPosition(mx, my);
particles.push_back(tempp); // change particles to std::list<Particle>

的Presto。你写的代码越少,你就不会爆炸。

答案 3 :(得分:2)

您正在将pointer放入容器中,然后将其删除,这是一个问题。 push_back会复制pointer的值而不是pointer的内容,因此当您致电delete时,容器中的pointer将不再有效。所以现在你有一个悬空指针,当你取消引用它时,这将是未定义的行为,但很可能是崩溃。

答案 4 :(得分:2)

我认为,解决方案在于您的第3行代码。请注意,粒子是指向粒子的指针的向量?好吧,在第3行中,您创建指针的副本并将其插入列表中。在下一行中,您释放该指针指向的内存。 列表不存储您的粒子 - 它只存储粒子的内存地址因此,当您删除粒子时,您告诉编译器重新使用包含有效数据的内存。

所以,虽然评论第4行会让问题消失,但实际上并没有崩溃 - 没有理由这样做。可能的情况是,当尝试使用曾经是你的的内存做某事时它会崩溃,但在第3行被释放。

您可以将列表存储为实际的粒子作为修复。