C++ 内存释放冻结了我的程序

C++ 内存释放冻结了我的程序,c++,pointers,memory-management,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 Partic

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

我正在制作具有粒子的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*tempp=新粒子();
tempp->setPosition(mx,my);
粒子。向后推(tempp);//粒子类型=标准::列表

删除tempp;// 根据发布的代码,
粒子
容器将包含悬空指针。任何试图取消引用这些的行为都是未定义的行为。我假设它们以后会被使用,否则它们的存储似乎毫无意义


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

将指针推入列表时,只会推送实际指针的副本,而不会复制其指向的内容。这意味着在
推回
后,有两个指针指向同一内存


如果然后释放该内存,则有一个指向可用内存的指针,该指针现在无效。

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

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

因此,当评论第四行使问题消失时,它实际上并没有崩溃——没有理由这样做。可能的情况是,它在尝试使用以前属于您的内存执行某些操作时崩溃,但在第3行中被释放


您可以让列表将实际粒子存储为固定值。

当我看到
新建
和几行之后的
删除
时,我宁愿看到使用的堆栈。除非
Particle
非常庞大(我对此表示怀疑),否则您可以将代码更改为:

Particle tempp;
tempp.setPosition(mx, my);
particles.push_back(tempp); // change particles to std::list<Particle>
粒子节拍;
临时设置位置(mx,my);
粒子。向后推(tempp);//将粒子更改为std::list

普雷斯托。你写的代码更少,就不会爆炸

您正在向向量添加指向tempp的指针-删除tempp后它指向什么?为什么要将tempp推到列表中,然后在后面的行中删除它?您的列表包含指向垃圾的指针,任何尝试访问它们的行为都可能导致程序崩溃。因此,在到达方法末尾后,指向tempp的指针仍然存在?如果我删除它,内存将被覆盖?@Broxzier您的列表不是函数的本地列表,因此即使在方法之外也存在。当您删除时,实际分配的内存被释放(可重复使用//它可能被覆盖,只是在那里。但它不在那里供您使用,它的UB用于取消引用),指针仍然包含地址。列表未超出范围,因此它仍然具有带地址的指针。您可能正在取消对
已删除的
内存地址的引用(可能是为了在屏幕上绘制该点,或者可能在超时后尝试擦除该点,然后将其冻结),为什么创建第二个点(第一个点仍然存在)会导致问题?每次调用时都会调用click处理程序,似乎函数的
tempp
是本地的,并且会进行
new
内存分配。(我同意悬空的指针)@SuvP,第一个指针不存在,因为它已经被
delete
d立即删除。如果第二个
粒子
的创建访问了
粒子
中的一个悬空指针,则该行为是未定义的行为,以及该行为的可能原因。查看当前代码并假设其他地方没有发生任何其他情况,则该列表不会在其他任何地方使用。(操作只是添加地址并删除内存//我知道)那么应该不会有问题吗?(除了悬挂的指针)。因此,OP可能正在访问其他地方的
列表
,这可能是导致问题的原因?[只是想澄清我的疑问]@SuvP,是的。指向释放内存的指针本身不是问题,您可以打印指向释放内存的指针的地址。您不能做的是引用指向解除分配内存(或未分配内存)的指针。在代码的其他地方,它可能会取消引用添加到容器中的一个指针。@Broxzier,代码的其余部分对我不可用,但错误可能是任何试图使用(取消引用)粒子中任何指针的代码。
。谢谢回答。当然,这是可行的,但我想知道在这种情况下是什么导致了问题,而不是解决方案。没有调用delete或使用更改向量来存储实际粒子,它已经工作得很好了。@Broxzier它工作得不好,只是没有爆炸。无论你新增了什么,你都必须删除。您的新代码和未删除的代码正在泄漏内存。这些天我们有很多,所以它不会伤害你,但它不工作的好。没有理由在thi中使用堆